PageRenderTime 67ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/pandas/tests/test_graphics.py

http://github.com/pydata/pandas
Python | 2578 lines | 2124 code | 300 blank | 154 comment | 145 complexity | 8fe4ffa60ffe4a5bf6ca69d9d11d5e58 MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0
  1. #!/usr/bin/env python
  2. # coding: utf-8
  3. import nose
  4. import itertools
  5. import os
  6. import string
  7. from distutils.version import LooseVersion
  8. from datetime import datetime, date
  9. from pandas import Series, DataFrame, MultiIndex, PeriodIndex, date_range
  10. from pandas.compat import (range, lrange, StringIO, lmap, lzip, u, zip,
  11. iteritems, OrderedDict)
  12. from pandas.util.decorators import cache_readonly
  13. import pandas.core.common as com
  14. import pandas.util.testing as tm
  15. from pandas.util.testing import ensure_clean
  16. from pandas.core.config import set_option
  17. import numpy as np
  18. from numpy import random
  19. from numpy.random import rand, randn
  20. from numpy.testing import assert_array_equal, assert_allclose
  21. from numpy.testing.decorators import slow
  22. import pandas.tools.plotting as plotting
  23. def _skip_if_no_scipy_gaussian_kde():
  24. try:
  25. import scipy
  26. from scipy.stats import gaussian_kde
  27. except ImportError:
  28. raise nose.SkipTest("scipy version doesn't support gaussian_kde")
  29. def _ok_for_gaussian_kde(kind):
  30. if kind in ['kde','density']:
  31. try:
  32. import scipy
  33. from scipy.stats import gaussian_kde
  34. except ImportError:
  35. return False
  36. return True
  37. @tm.mplskip
  38. class TestPlotBase(tm.TestCase):
  39. def setUp(self):
  40. import matplotlib as mpl
  41. mpl.rcdefaults()
  42. n = 100
  43. with tm.RNGContext(42):
  44. gender = tm.choice(['Male', 'Female'], size=n)
  45. classroom = tm.choice(['A', 'B', 'C'], size=n)
  46. self.hist_df = DataFrame({'gender': gender,
  47. 'classroom': classroom,
  48. 'height': random.normal(66, 4, size=n),
  49. 'weight': random.normal(161, 32, size=n),
  50. 'category': random.randint(4, size=n)})
  51. def tearDown(self):
  52. tm.close()
  53. @cache_readonly
  54. def plt(self):
  55. import matplotlib.pyplot as plt
  56. return plt
  57. @cache_readonly
  58. def colorconverter(self):
  59. import matplotlib.colors as colors
  60. return colors.colorConverter
  61. def _check_legend_labels(self, axes, labels=None, visible=True):
  62. """
  63. Check each axes has expected legend labels
  64. Parameters
  65. ----------
  66. axes : matplotlib Axes object, or its list-like
  67. labels : list-like
  68. expected legend labels
  69. visible : bool
  70. expected legend visibility. labels are checked only when visible is True
  71. """
  72. if visible and (labels is None):
  73. raise ValueError('labels must be specified when visible is True')
  74. axes = self._flatten_visible(axes)
  75. for ax in axes:
  76. if visible:
  77. self.assertTrue(ax.get_legend() is not None)
  78. self._check_text_labels(ax.get_legend().get_texts(), labels)
  79. else:
  80. self.assertTrue(ax.get_legend() is None)
  81. def _check_data(self, xp, rs):
  82. """
  83. Check each axes has identical lines
  84. Parameters
  85. ----------
  86. xp : matplotlib Axes object
  87. rs : matplotlib Axes object
  88. """
  89. xp_lines = xp.get_lines()
  90. rs_lines = rs.get_lines()
  91. def check_line(xpl, rsl):
  92. xpdata = xpl.get_xydata()
  93. rsdata = rsl.get_xydata()
  94. assert_allclose(xpdata, rsdata)
  95. self.assertEqual(len(xp_lines), len(rs_lines))
  96. [check_line(xpl, rsl) for xpl, rsl in zip(xp_lines, rs_lines)]
  97. tm.close()
  98. def _check_visible(self, collections, visible=True):
  99. """
  100. Check each artist is visible or not
  101. Parameters
  102. ----------
  103. collections : list-like
  104. list or collection of target artist
  105. visible : bool
  106. expected visibility
  107. """
  108. for patch in collections:
  109. self.assertEqual(patch.get_visible(), visible)
  110. def _get_colors_mapped(self, series, colors):
  111. unique = series.unique()
  112. # unique and colors length can be differed
  113. # depending on slice value
  114. mapped = dict(zip(unique, colors))
  115. return [mapped[v] for v in series.values]
  116. def _check_colors(self, collections, linecolors=None, facecolors=None,
  117. mapping=None):
  118. """
  119. Check each artist has expected line colors and face colors
  120. Parameters
  121. ----------
  122. collections : list-like
  123. list or collection of target artist
  124. linecolors : list-like which has the same length as collections
  125. list of expected line colors
  126. facecolors : list-like which has the same length as collections
  127. list of expected face colors
  128. mapping : Series
  129. Series used for color grouping key
  130. used for andrew_curves, parallel_coordinates, radviz test
  131. """
  132. from matplotlib.lines import Line2D
  133. from matplotlib.collections import Collection
  134. conv = self.colorconverter
  135. if linecolors is not None:
  136. if mapping is not None:
  137. linecolors = self._get_colors_mapped(mapping, linecolors)
  138. linecolors = linecolors[:len(collections)]
  139. self.assertEqual(len(collections), len(linecolors))
  140. for patch, color in zip(collections, linecolors):
  141. if isinstance(patch, Line2D):
  142. result = patch.get_color()
  143. # Line2D may contains string color expression
  144. result = conv.to_rgba(result)
  145. else:
  146. result = patch.get_edgecolor()
  147. expected = conv.to_rgba(color)
  148. self.assertEqual(result, expected)
  149. if facecolors is not None:
  150. if mapping is not None:
  151. facecolors = self._get_colors_mapped(mapping, facecolors)
  152. facecolors = facecolors[:len(collections)]
  153. self.assertEqual(len(collections), len(facecolors))
  154. for patch, color in zip(collections, facecolors):
  155. if isinstance(patch, Collection):
  156. # returned as list of np.array
  157. result = patch.get_facecolor()[0]
  158. else:
  159. result = patch.get_facecolor()
  160. if isinstance(result, np.ndarray):
  161. result = tuple(result)
  162. expected = conv.to_rgba(color)
  163. self.assertEqual(result, expected)
  164. def _check_text_labels(self, texts, expected):
  165. """
  166. Check each text has expected labels
  167. Parameters
  168. ----------
  169. texts : matplotlib Text object, or its list-like
  170. target text, or its list
  171. expected : str or list-like which has the same length as texts
  172. expected text label, or its list
  173. """
  174. if not com.is_list_like(texts):
  175. self.assertEqual(texts.get_text(), expected)
  176. else:
  177. labels = [t.get_text() for t in texts]
  178. self.assertEqual(len(labels), len(expected))
  179. for l, e in zip(labels, expected):
  180. self.assertEqual(l, e)
  181. def _check_ticks_props(self, axes, xlabelsize=None, xrot=None,
  182. ylabelsize=None, yrot=None):
  183. """
  184. Check each axes has expected tick properties
  185. Parameters
  186. ----------
  187. axes : matplotlib Axes object, or its list-like
  188. xlabelsize : number
  189. expected xticks font size
  190. xrot : number
  191. expected xticks rotation
  192. ylabelsize : number
  193. expected yticks font size
  194. yrot : number
  195. expected yticks rotation
  196. """
  197. axes = self._flatten_visible(axes)
  198. for ax in axes:
  199. if xlabelsize or xrot:
  200. xtick = ax.get_xticklabels()[0]
  201. if xlabelsize is not None:
  202. self.assertAlmostEqual(xtick.get_fontsize(), xlabelsize)
  203. if xrot is not None:
  204. self.assertAlmostEqual(xtick.get_rotation(), xrot)
  205. if ylabelsize or yrot:
  206. ytick = ax.get_yticklabels()[0]
  207. if ylabelsize is not None:
  208. self.assertAlmostEqual(ytick.get_fontsize(), ylabelsize)
  209. if yrot is not None:
  210. self.assertAlmostEqual(ytick.get_rotation(), yrot)
  211. def _check_ax_scales(self, axes, xaxis='linear', yaxis='linear'):
  212. """
  213. Check each axes has expected scales
  214. Parameters
  215. ----------
  216. axes : matplotlib Axes object, or its list-like
  217. xaxis : {'linear', 'log'}
  218. expected xaxis scale
  219. yaxis : {'linear', 'log'}
  220. expected yaxis scale
  221. """
  222. axes = self._flatten_visible(axes)
  223. for ax in axes:
  224. self.assertEqual(ax.xaxis.get_scale(), xaxis)
  225. self.assertEqual(ax.yaxis.get_scale(), yaxis)
  226. def _check_axes_shape(self, axes, axes_num=None, layout=None, figsize=(8.0, 6.0)):
  227. """
  228. Check expected number of axes is drawn in expected layout
  229. Parameters
  230. ----------
  231. axes : matplotlib Axes object, or its list-like
  232. axes_num : number
  233. expected number of axes. Unnecessary axes should be set to invisible.
  234. layout : tuple
  235. expected layout, (expected number of rows , columns)
  236. figsize : tuple
  237. expected figsize. default is matplotlib default
  238. """
  239. visible_axes = self._flatten_visible(axes)
  240. if axes_num is not None:
  241. self.assertEqual(len(visible_axes), axes_num)
  242. for ax in visible_axes:
  243. # check something drawn on visible axes
  244. self.assertTrue(len(ax.get_children()) > 0)
  245. if layout is not None:
  246. result = self._get_axes_layout(plotting._flatten(axes))
  247. self.assertEqual(result, layout)
  248. self.assert_numpy_array_equal(np.round(visible_axes[0].figure.get_size_inches()),
  249. np.array(figsize))
  250. def _get_axes_layout(self, axes):
  251. x_set = set()
  252. y_set = set()
  253. for ax in axes:
  254. # check axes coordinates to estimate layout
  255. points = ax.get_position().get_points()
  256. x_set.add(points[0][0])
  257. y_set.add(points[0][1])
  258. return (len(y_set), len(x_set))
  259. def _flatten_visible(self, axes):
  260. """
  261. Flatten axes, and filter only visible
  262. Parameters
  263. ----------
  264. axes : matplotlib Axes object, or its list-like
  265. """
  266. axes = plotting._flatten(axes)
  267. axes = [ax for ax in axes if ax.get_visible()]
  268. return axes
  269. def _check_has_errorbars(self, axes, xerr=0, yerr=0):
  270. """
  271. Check axes has expected number of errorbars
  272. Parameters
  273. ----------
  274. axes : matplotlib Axes object, or its list-like
  275. xerr : number
  276. expected number of x errorbar
  277. yerr : number
  278. expected number of y errorbar
  279. """
  280. axes = self._flatten_visible(axes)
  281. for ax in axes:
  282. containers = ax.containers
  283. xerr_count = 0
  284. yerr_count = 0
  285. for c in containers:
  286. has_xerr = getattr(c, 'has_xerr', False)
  287. has_yerr = getattr(c, 'has_yerr', False)
  288. if has_xerr:
  289. xerr_count += 1
  290. if has_yerr:
  291. yerr_count += 1
  292. self.assertEqual(xerr, xerr_count)
  293. self.assertEqual(yerr, yerr_count)
  294. def _check_box_return_type(self, returned, return_type, expected_keys=None):
  295. """
  296. Check box returned type is correct
  297. Parameters
  298. ----------
  299. returned : object to be tested, returned from boxplot
  300. return_type : str
  301. return_type passed to boxplot
  302. expected_keys : list-like, optional
  303. group labels in subplot case. If not passed,
  304. the function checks assuming boxplot uses single ax
  305. """
  306. from matplotlib.axes import Axes
  307. types = {'dict': dict, 'axes': Axes, 'both': tuple}
  308. if expected_keys is None:
  309. # should be fixed when the returning default is changed
  310. if return_type is None:
  311. return_type = 'dict'
  312. self.assertTrue(isinstance(returned, types[return_type]))
  313. if return_type == 'both':
  314. self.assertIsInstance(returned.ax, Axes)
  315. self.assertIsInstance(returned.lines, dict)
  316. else:
  317. # should be fixed when the returning default is changed
  318. if return_type is None:
  319. for r in self._flatten_visible(returned):
  320. self.assertIsInstance(r, Axes)
  321. return
  322. self.assertTrue(isinstance(returned, OrderedDict))
  323. self.assertEqual(sorted(returned.keys()), sorted(expected_keys))
  324. for key, value in iteritems(returned):
  325. self.assertTrue(isinstance(value, types[return_type]))
  326. # check returned dict has correct mapping
  327. if return_type == 'axes':
  328. self.assertEqual(value.get_title(), key)
  329. elif return_type == 'both':
  330. self.assertEqual(value.ax.get_title(), key)
  331. self.assertIsInstance(value.ax, Axes)
  332. self.assertIsInstance(value.lines, dict)
  333. elif return_type == 'dict':
  334. line = value['medians'][0]
  335. self.assertEqual(line.get_axes().get_title(), key)
  336. else:
  337. raise AssertionError
  338. @tm.mplskip
  339. class TestSeriesPlots(TestPlotBase):
  340. def setUp(self):
  341. TestPlotBase.setUp(self)
  342. import matplotlib as mpl
  343. mpl.rcdefaults()
  344. self.mpl_le_1_2_1 = str(mpl.__version__) <= LooseVersion('1.2.1')
  345. self.ts = tm.makeTimeSeries()
  346. self.ts.name = 'ts'
  347. self.series = tm.makeStringSeries()
  348. self.series.name = 'series'
  349. self.iseries = tm.makePeriodSeries()
  350. self.iseries.name = 'iseries'
  351. @slow
  352. def test_plot(self):
  353. _check_plot_works(self.ts.plot, label='foo')
  354. _check_plot_works(self.ts.plot, use_index=False)
  355. axes = _check_plot_works(self.ts.plot, rot=0)
  356. self._check_ticks_props(axes, xrot=0)
  357. ax = _check_plot_works(self.ts.plot, style='.', logy=True)
  358. self._check_ax_scales(ax, yaxis='log')
  359. ax = _check_plot_works(self.ts.plot, style='.', logx=True)
  360. self._check_ax_scales(ax, xaxis='log')
  361. ax = _check_plot_works(self.ts.plot, style='.', loglog=True)
  362. self._check_ax_scales(ax, xaxis='log', yaxis='log')
  363. _check_plot_works(self.ts[:10].plot, kind='bar')
  364. _check_plot_works(self.ts.plot, kind='area', stacked=False)
  365. _check_plot_works(self.iseries.plot)
  366. for kind in ['line', 'bar', 'barh', 'kde']:
  367. if not _ok_for_gaussian_kde(kind):
  368. continue
  369. _check_plot_works(self.series[:5].plot, kind=kind)
  370. _check_plot_works(self.series[:10].plot, kind='barh')
  371. ax = _check_plot_works(Series(randn(10)).plot, kind='bar', color='black')
  372. self._check_colors([ax.patches[0]], facecolors=['black'])
  373. # GH 6951
  374. ax = _check_plot_works(self.ts.plot, subplots=True)
  375. self._check_axes_shape(ax, axes_num=1, layout=(1, 1))
  376. @slow
  377. def test_plot_figsize_and_title(self):
  378. # figsize and title
  379. ax = self.series.plot(title='Test', figsize=(16, 8))
  380. self._check_text_labels(ax.title, 'Test')
  381. self._check_axes_shape(ax, axes_num=1, layout=(1, 1), figsize=(16, 8))
  382. def test_ts_line_lim(self):
  383. ax = self.ts.plot()
  384. xmin, xmax = ax.get_xlim()
  385. lines = ax.get_lines()
  386. self.assertEqual(xmin, lines[0].get_data(orig=False)[0][0])
  387. self.assertEqual(xmax, lines[0].get_data(orig=False)[0][-1])
  388. tm.close()
  389. ax = self.ts.plot(secondary_y=True)
  390. xmin, xmax = ax.get_xlim()
  391. lines = ax.get_lines()
  392. self.assertEqual(xmin, lines[0].get_data(orig=False)[0][0])
  393. self.assertEqual(xmax, lines[0].get_data(orig=False)[0][-1])
  394. def test_ts_area_lim(self):
  395. ax = self.ts.plot(kind='area', stacked=False)
  396. xmin, xmax = ax.get_xlim()
  397. line = ax.get_lines()[0].get_data(orig=False)[0]
  398. self.assertEqual(xmin, line[0])
  399. self.assertEqual(xmax, line[-1])
  400. tm.close()
  401. # GH 7471
  402. ax = self.ts.plot(kind='area', stacked=False, x_compat=True)
  403. xmin, xmax = ax.get_xlim()
  404. line = ax.get_lines()[0].get_data(orig=False)[0]
  405. self.assertEqual(xmin, line[0])
  406. self.assertEqual(xmax, line[-1])
  407. tm.close()
  408. tz_ts = self.ts.copy()
  409. tz_ts.index = tz_ts.tz_localize('GMT').tz_convert('CET')
  410. ax = tz_ts.plot(kind='area', stacked=False, x_compat=True)
  411. xmin, xmax = ax.get_xlim()
  412. line = ax.get_lines()[0].get_data(orig=False)[0]
  413. self.assertEqual(xmin, line[0])
  414. self.assertEqual(xmax, line[-1])
  415. tm.close()
  416. ax = tz_ts.plot(kind='area', stacked=False, secondary_y=True)
  417. xmin, xmax = ax.get_xlim()
  418. line = ax.get_lines()[0].get_data(orig=False)[0]
  419. self.assertEqual(xmin, line[0])
  420. self.assertEqual(xmax, line[-1])
  421. def test_line_area_nan_series(self):
  422. values = [1, 2, np.nan, 3]
  423. s = Series(values)
  424. ts = Series(values, index=tm.makeDateIndex(k=4))
  425. for d in [s, ts]:
  426. ax = _check_plot_works(d.plot)
  427. masked = ax.lines[0].get_ydata()
  428. # remove nan for comparison purpose
  429. self.assert_numpy_array_equal(np.delete(masked.data, 2), np.array([1, 2, 3]))
  430. self.assert_numpy_array_equal(masked.mask, np.array([False, False, True, False]))
  431. expected = np.array([1, 2, 0, 3])
  432. ax = _check_plot_works(d.plot, stacked=True)
  433. self.assert_numpy_array_equal(ax.lines[0].get_ydata(), expected)
  434. ax = _check_plot_works(d.plot, kind='area')
  435. self.assert_numpy_array_equal(ax.lines[0].get_ydata(), expected)
  436. ax = _check_plot_works(d.plot, kind='area', stacked=False)
  437. self.assert_numpy_array_equal(ax.lines[0].get_ydata(), expected)
  438. @slow
  439. def test_bar_log(self):
  440. expected = np.array([1., 10., 100., 1000.])
  441. if not self.mpl_le_1_2_1:
  442. expected = np.hstack((.1, expected, 1e4))
  443. ax = Series([200, 500]).plot(log=True, kind='bar')
  444. assert_array_equal(ax.yaxis.get_ticklocs(), expected)
  445. @slow
  446. def test_bar_ignore_index(self):
  447. df = Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])
  448. ax = df.plot(kind='bar', use_index=False)
  449. self._check_text_labels(ax.get_xticklabels(), ['0', '1', '2', '3'])
  450. def test_rotation(self):
  451. df = DataFrame(randn(5, 5))
  452. axes = df.plot(rot=30)
  453. self._check_ticks_props(axes, xrot=30)
  454. def test_irregular_datetime(self):
  455. rng = date_range('1/1/2000', '3/1/2000')
  456. rng = rng[[0, 1, 2, 3, 5, 9, 10, 11, 12]]
  457. ser = Series(randn(len(rng)), rng)
  458. ax = ser.plot()
  459. xp = datetime(1999, 1, 1).toordinal()
  460. ax.set_xlim('1/1/1999', '1/1/2001')
  461. self.assertEqual(xp, ax.get_xlim()[0])
  462. @slow
  463. def test_pie_series(self):
  464. # if sum of values is less than 1.0, pie handle them as rate and draw semicircle.
  465. series = Series(np.random.randint(1, 5),
  466. index=['a', 'b', 'c', 'd', 'e'], name='YLABEL')
  467. ax = _check_plot_works(series.plot, kind='pie')
  468. self._check_text_labels(ax.texts, series.index)
  469. self.assertEqual(ax.get_ylabel(), 'YLABEL')
  470. # without wedge labels
  471. ax = _check_plot_works(series.plot, kind='pie', labels=None)
  472. self._check_text_labels(ax.texts, [''] * 5)
  473. # with less colors than elements
  474. color_args = ['r', 'g', 'b']
  475. ax = _check_plot_works(series.plot, kind='pie', colors=color_args)
  476. color_expected = ['r', 'g', 'b', 'r', 'g']
  477. self._check_colors(ax.patches, facecolors=color_expected)
  478. # with labels and colors
  479. labels = ['A', 'B', 'C', 'D', 'E']
  480. color_args = ['r', 'g', 'b', 'c', 'm']
  481. ax = _check_plot_works(series.plot, kind='pie', labels=labels, colors=color_args)
  482. self._check_text_labels(ax.texts, labels)
  483. self._check_colors(ax.patches, facecolors=color_args)
  484. # with autopct and fontsize
  485. ax = _check_plot_works(series.plot, kind='pie', colors=color_args,
  486. autopct='%.2f', fontsize=7)
  487. pcts = ['{0:.2f}'.format(s * 100) for s in series.values / float(series.sum())]
  488. iters = [iter(series.index), iter(pcts)]
  489. expected_texts = list(next(it) for it in itertools.cycle(iters))
  490. self._check_text_labels(ax.texts, expected_texts)
  491. for t in ax.texts:
  492. self.assertEqual(t.get_fontsize(), 7)
  493. # includes negative value
  494. with tm.assertRaises(ValueError):
  495. series = Series([1, 2, 0, 4, -1], index=['a', 'b', 'c', 'd', 'e'])
  496. series.plot(kind='pie')
  497. # includes nan
  498. series = Series([1, 2, np.nan, 4],
  499. index=['a', 'b', 'c', 'd'], name='YLABEL')
  500. ax = _check_plot_works(series.plot, kind='pie')
  501. self._check_text_labels(ax.texts, series.index)
  502. @slow
  503. def test_hist(self):
  504. _check_plot_works(self.ts.hist)
  505. _check_plot_works(self.ts.hist, grid=False)
  506. _check_plot_works(self.ts.hist, figsize=(8, 10))
  507. _check_plot_works(self.ts.hist, by=self.ts.index.month)
  508. _check_plot_works(self.ts.hist, by=self.ts.index.month, bins=5)
  509. fig, ax = self.plt.subplots(1, 1)
  510. _check_plot_works(self.ts.hist, ax=ax)
  511. _check_plot_works(self.ts.hist, ax=ax, figure=fig)
  512. _check_plot_works(self.ts.hist, figure=fig)
  513. tm.close()
  514. fig, (ax1, ax2) = self.plt.subplots(1, 2)
  515. _check_plot_works(self.ts.hist, figure=fig, ax=ax1)
  516. _check_plot_works(self.ts.hist, figure=fig, ax=ax2)
  517. with tm.assertRaises(ValueError):
  518. self.ts.hist(by=self.ts.index, figure=fig)
  519. @slow
  520. def test_hist_bins(self):
  521. df = DataFrame(np.random.randn(10, 2))
  522. ax = df.hist(bins=2)[0][0]
  523. self.assertEqual(len(ax.patches), 2)
  524. @slow
  525. def test_hist_layout(self):
  526. df = self.hist_df
  527. with tm.assertRaises(ValueError):
  528. df.height.hist(layout=(1, 1))
  529. with tm.assertRaises(ValueError):
  530. df.height.hist(layout=[1, 1])
  531. @slow
  532. def test_hist_layout_with_by(self):
  533. df = self.hist_df
  534. axes = _check_plot_works(df.height.hist, by=df.gender, layout=(2, 1))
  535. self._check_axes_shape(axes, axes_num=2, layout=(2, 1))
  536. axes = _check_plot_works(df.height.hist, by=df.category, layout=(4, 1))
  537. self._check_axes_shape(axes, axes_num=4, layout=(4, 1))
  538. axes = _check_plot_works(df.height.hist, by=df.classroom, layout=(2, 2))
  539. self._check_axes_shape(axes, axes_num=3, layout=(2, 2))
  540. axes = _check_plot_works(df.height.hist, by=df.category, layout=(4, 2), figsize=(12, 7))
  541. self._check_axes_shape(axes, axes_num=4, layout=(4, 2), figsize=(12, 7))
  542. @slow
  543. def test_hist_no_overlap(self):
  544. from matplotlib.pyplot import subplot, gcf
  545. x = Series(randn(2))
  546. y = Series(randn(2))
  547. subplot(121)
  548. x.hist()
  549. subplot(122)
  550. y.hist()
  551. fig = gcf()
  552. axes = fig.get_axes()
  553. self.assertEqual(len(axes), 2)
  554. @slow
  555. def test_plot_fails_with_dupe_color_and_style(self):
  556. x = Series(randn(2))
  557. with tm.assertRaises(ValueError):
  558. x.plot(style='k--', color='k')
  559. @slow
  560. def test_hist_by_no_extra_plots(self):
  561. df = self.hist_df
  562. axes = df.height.hist(by=df.gender)
  563. self.assertEqual(len(self.plt.get_fignums()), 1)
  564. def test_plot_fails_when_ax_differs_from_figure(self):
  565. from pylab import figure
  566. fig1 = figure()
  567. fig2 = figure()
  568. ax1 = fig1.add_subplot(111)
  569. with tm.assertRaises(AssertionError):
  570. self.ts.hist(ax=ax1, figure=fig2)
  571. @slow
  572. def test_kde(self):
  573. tm._skip_if_no_scipy()
  574. _skip_if_no_scipy_gaussian_kde()
  575. _check_plot_works(self.ts.plot, kind='kde')
  576. _check_plot_works(self.ts.plot, kind='density')
  577. ax = self.ts.plot(kind='kde', logy=True)
  578. self._check_ax_scales(ax, yaxis='log')
  579. @slow
  580. def test_kde_kwargs(self):
  581. tm._skip_if_no_scipy()
  582. _skip_if_no_scipy_gaussian_kde()
  583. from numpy import linspace
  584. _check_plot_works(self.ts.plot, kind='kde', bw_method=.5, ind=linspace(-100,100,20))
  585. _check_plot_works(self.ts.plot, kind='density', bw_method=.5, ind=linspace(-100,100,20))
  586. ax = self.ts.plot(kind='kde', logy=True, bw_method=.5, ind=linspace(-100,100,20))
  587. self._check_ax_scales(ax, yaxis='log')
  588. @slow
  589. def test_kde_color(self):
  590. tm._skip_if_no_scipy()
  591. _skip_if_no_scipy_gaussian_kde()
  592. ax = self.ts.plot(kind='kde', logy=True, color='r')
  593. self._check_ax_scales(ax, yaxis='log')
  594. lines = ax.get_lines()
  595. self.assertEqual(len(lines), 1)
  596. self._check_colors(lines, ['r'])
  597. @slow
  598. def test_autocorrelation_plot(self):
  599. from pandas.tools.plotting import autocorrelation_plot
  600. _check_plot_works(autocorrelation_plot, self.ts)
  601. _check_plot_works(autocorrelation_plot, self.ts.values)
  602. ax = autocorrelation_plot(self.ts, label='Test')
  603. self._check_legend_labels(ax, labels=['Test'])
  604. @slow
  605. def test_lag_plot(self):
  606. from pandas.tools.plotting import lag_plot
  607. _check_plot_works(lag_plot, self.ts)
  608. _check_plot_works(lag_plot, self.ts, lag=5)
  609. @slow
  610. def test_bootstrap_plot(self):
  611. from pandas.tools.plotting import bootstrap_plot
  612. _check_plot_works(bootstrap_plot, self.ts, size=10)
  613. def test_invalid_plot_data(self):
  614. s = Series(list('abcd'))
  615. for kind in plotting._common_kinds:
  616. if not _ok_for_gaussian_kde(kind):
  617. continue
  618. with tm.assertRaises(TypeError):
  619. s.plot(kind=kind)
  620. @slow
  621. def test_valid_object_plot(self):
  622. s = Series(lrange(10), dtype=object)
  623. for kind in plotting._common_kinds:
  624. if not _ok_for_gaussian_kde(kind):
  625. continue
  626. _check_plot_works(s.plot, kind=kind)
  627. def test_partially_invalid_plot_data(self):
  628. s = Series(['a', 'b', 1.0, 2])
  629. for kind in plotting._common_kinds:
  630. if not _ok_for_gaussian_kde(kind):
  631. continue
  632. with tm.assertRaises(TypeError):
  633. s.plot(kind=kind)
  634. def test_invalid_kind(self):
  635. s = Series([1, 2])
  636. with tm.assertRaises(ValueError):
  637. s.plot(kind='aasdf')
  638. @slow
  639. def test_dup_datetime_index_plot(self):
  640. dr1 = date_range('1/1/2009', periods=4)
  641. dr2 = date_range('1/2/2009', periods=4)
  642. index = dr1.append(dr2)
  643. values = randn(index.size)
  644. s = Series(values, index=index)
  645. _check_plot_works(s.plot)
  646. @slow
  647. def test_errorbar_plot(self):
  648. s = Series(np.arange(10), name='x')
  649. s_err = np.random.randn(10)
  650. d_err = DataFrame(randn(10, 2), index=s.index, columns=['x', 'y'])
  651. # test line and bar plots
  652. kinds = ['line', 'bar']
  653. for kind in kinds:
  654. ax = _check_plot_works(s.plot, yerr=Series(s_err), kind=kind)
  655. self._check_has_errorbars(ax, xerr=0, yerr=1)
  656. ax = _check_plot_works(s.plot, yerr=s_err, kind=kind)
  657. self._check_has_errorbars(ax, xerr=0, yerr=1)
  658. ax = _check_plot_works(s.plot, yerr=s_err.tolist(), kind=kind)
  659. self._check_has_errorbars(ax, xerr=0, yerr=1)
  660. ax = _check_plot_works(s.plot, yerr=d_err, kind=kind)
  661. self._check_has_errorbars(ax, xerr=0, yerr=1)
  662. ax = _check_plot_works(s.plot, xerr=0.2, yerr=0.2, kind=kind)
  663. self._check_has_errorbars(ax, xerr=1, yerr=1)
  664. ax = _check_plot_works(s.plot, xerr=s_err)
  665. self._check_has_errorbars(ax, xerr=1, yerr=0)
  666. # test time series plotting
  667. ix = date_range('1/1/2000', '1/1/2001', freq='M')
  668. ts = Series(np.arange(12), index=ix, name='x')
  669. ts_err = Series(np.random.randn(12), index=ix)
  670. td_err = DataFrame(randn(12, 2), index=ix, columns=['x', 'y'])
  671. ax = _check_plot_works(ts.plot, yerr=ts_err)
  672. self._check_has_errorbars(ax, xerr=0, yerr=1)
  673. ax = _check_plot_works(ts.plot, yerr=td_err)
  674. self._check_has_errorbars(ax, xerr=0, yerr=1)
  675. # check incorrect lengths and types
  676. with tm.assertRaises(ValueError):
  677. s.plot(yerr=np.arange(11))
  678. s_err = ['zzz']*10
  679. with tm.assertRaises(TypeError):
  680. s.plot(yerr=s_err)
  681. def test_table(self):
  682. _check_plot_works(self.series.plot, table=True)
  683. _check_plot_works(self.series.plot, table=self.series)
  684. @tm.mplskip
  685. class TestDataFramePlots(TestPlotBase):
  686. def setUp(self):
  687. TestPlotBase.setUp(self)
  688. import matplotlib as mpl
  689. mpl.rcdefaults()
  690. self.mpl_le_1_2_1 = str(mpl.__version__) <= LooseVersion('1.2.1')
  691. self.tdf = tm.makeTimeDataFrame()
  692. self.hexbin_df = DataFrame({"A": np.random.uniform(size=20),
  693. "B": np.random.uniform(size=20),
  694. "C": np.arange(20) + np.random.uniform(size=20)})
  695. from pandas import read_csv
  696. path = os.path.join(curpath(), 'data', 'iris.csv')
  697. self.iris = read_csv(path)
  698. @slow
  699. def test_plot(self):
  700. df = self.tdf
  701. _check_plot_works(df.plot, grid=False)
  702. axes = _check_plot_works(df.plot, subplots=True)
  703. self._check_axes_shape(axes, axes_num=4, layout=(4, 1))
  704. _check_plot_works(df.plot, subplots=True, use_index=False)
  705. self._check_axes_shape(axes, axes_num=4, layout=(4, 1))
  706. df = DataFrame({'x': [1, 2], 'y': [3, 4]})
  707. with tm.assertRaises(TypeError):
  708. df.plot(kind='line', blarg=True)
  709. df = DataFrame(np.random.rand(10, 3),
  710. index=list(string.ascii_letters[:10]))
  711. _check_plot_works(df.plot, use_index=True)
  712. _check_plot_works(df.plot, sort_columns=False)
  713. _check_plot_works(df.plot, yticks=[1, 5, 10])
  714. _check_plot_works(df.plot, xticks=[1, 5, 10])
  715. _check_plot_works(df.plot, ylim=(-100, 100), xlim=(-100, 100))
  716. axes = _check_plot_works(df.plot, subplots=True, title='blah')
  717. self._check_axes_shape(axes, axes_num=3, layout=(3, 1))
  718. for ax in axes[:2]:
  719. self._check_visible(ax.get_xticklabels(), visible=False)
  720. self._check_visible([ax.xaxis.get_label()], visible=False)
  721. for ax in [axes[2]]:
  722. self._check_visible(ax.get_xticklabels())
  723. self._check_visible([ax.xaxis.get_label()])
  724. _check_plot_works(df.plot, title='blah')
  725. tuples = lzip(string.ascii_letters[:10], range(10))
  726. df = DataFrame(np.random.rand(10, 3),
  727. index=MultiIndex.from_tuples(tuples))
  728. _check_plot_works(df.plot, use_index=True)
  729. # unicode
  730. index = MultiIndex.from_tuples([(u('\u03b1'), 0),
  731. (u('\u03b1'), 1),
  732. (u('\u03b2'), 2),
  733. (u('\u03b2'), 3),
  734. (u('\u03b3'), 4),
  735. (u('\u03b3'), 5),
  736. (u('\u03b4'), 6),
  737. (u('\u03b4'), 7)], names=['i0', 'i1'])
  738. columns = MultiIndex.from_tuples([('bar', u('\u0394')),
  739. ('bar', u('\u0395'))], names=['c0',
  740. 'c1'])
  741. df = DataFrame(np.random.randint(0, 10, (8, 2)),
  742. columns=columns,
  743. index=index)
  744. _check_plot_works(df.plot, title=u('\u03A3'))
  745. # GH 6951
  746. # Test with single column
  747. df = DataFrame({'x': np.random.rand(10)})
  748. axes = _check_plot_works(df.plot, kind='bar', subplots=True)
  749. self._check_axes_shape(axes, axes_num=1, layout=(1, 1))
  750. # When ax is supplied and required number of axes is 1,
  751. # passed ax should be used:
  752. fig, ax = self.plt.subplots()
  753. axes = df.plot(kind='bar', subplots=True, ax=ax)
  754. self.assertEqual(len(axes), 1)
  755. self.assertIs(ax.get_axes(), axes[0])
  756. def test_nonnumeric_exclude(self):
  757. df = DataFrame({'A': ["x", "y", "z"], 'B': [1, 2, 3]})
  758. ax = df.plot()
  759. self.assertEqual(len(ax.get_lines()), 1) # B was plotted
  760. @slow
  761. def test_implicit_label(self):
  762. df = DataFrame(randn(10, 3), columns=['a', 'b', 'c'])
  763. ax = df.plot(x='a', y='b')
  764. self._check_text_labels(ax.xaxis.get_label(), 'a')
  765. @slow
  766. def test_explicit_label(self):
  767. df = DataFrame(randn(10, 3), columns=['a', 'b', 'c'])
  768. ax = df.plot(x='a', y='b', label='LABEL')
  769. self._check_text_labels(ax.xaxis.get_label(), 'LABEL')
  770. @slow
  771. def test_plot_xy(self):
  772. # columns.inferred_type == 'string'
  773. df = self.tdf
  774. self._check_data(df.plot(x=0, y=1),
  775. df.set_index('A')['B'].plot())
  776. self._check_data(df.plot(x=0), df.set_index('A').plot())
  777. self._check_data(df.plot(y=0), df.B.plot())
  778. self._check_data(df.plot(x='A', y='B'),
  779. df.set_index('A').B.plot())
  780. self._check_data(df.plot(x='A'), df.set_index('A').plot())
  781. self._check_data(df.plot(y='B'), df.B.plot())
  782. # columns.inferred_type == 'integer'
  783. df.columns = lrange(1, len(df.columns) + 1)
  784. self._check_data(df.plot(x=1, y=2),
  785. df.set_index(1)[2].plot())
  786. self._check_data(df.plot(x=1), df.set_index(1).plot())
  787. self._check_data(df.plot(y=1), df[1].plot())
  788. # figsize and title
  789. ax = df.plot(x=1, y=2, title='Test', figsize=(16, 8))
  790. self._check_text_labels(ax.title, 'Test')
  791. self._check_axes_shape(ax, axes_num=1, layout=(1, 1), figsize=(16., 8.))
  792. # columns.inferred_type == 'mixed'
  793. # TODO add MultiIndex test
  794. @slow
  795. def test_logscales(self):
  796. df = DataFrame({'a': np.arange(100)},
  797. index=np.arange(100))
  798. ax = df.plot(logy=True)
  799. self._check_ax_scales(ax, yaxis='log')
  800. ax = df.plot(logx=True)
  801. self._check_ax_scales(ax, xaxis='log')
  802. ax = df.plot(loglog=True)
  803. self._check_ax_scales(ax, xaxis='log', yaxis='log')
  804. @slow
  805. def test_xcompat(self):
  806. import pandas as pd
  807. df = self.tdf
  808. ax = df.plot(x_compat=True)
  809. lines = ax.get_lines()
  810. self.assertNotIsInstance(lines[0].get_xdata(), PeriodIndex)
  811. tm.close()
  812. pd.plot_params['xaxis.compat'] = True
  813. ax = df.plot()
  814. lines = ax.get_lines()
  815. self.assertNotIsInstance(lines[0].get_xdata(), PeriodIndex)
  816. tm.close()
  817. pd.plot_params['x_compat'] = False
  818. ax = df.plot()
  819. lines = ax.get_lines()
  820. tm.assert_isinstance(lines[0].get_xdata(), PeriodIndex)
  821. tm.close()
  822. # useful if you're plotting a bunch together
  823. with pd.plot_params.use('x_compat', True):
  824. ax = df.plot()
  825. lines = ax.get_lines()
  826. self.assertNotIsInstance(lines[0].get_xdata(), PeriodIndex)
  827. tm.close()
  828. ax = df.plot()
  829. lines = ax.get_lines()
  830. tm.assert_isinstance(lines[0].get_xdata(), PeriodIndex)
  831. def test_unsorted_index(self):
  832. df = DataFrame({'y': np.arange(100)},
  833. index=np.arange(99, -1, -1), dtype=np.int64)
  834. ax = df.plot()
  835. l = ax.get_lines()[0]
  836. rs = l.get_xydata()
  837. rs = Series(rs[:, 1], rs[:, 0], dtype=np.int64)
  838. tm.assert_series_equal(rs, df.y)
  839. @slow
  840. def test_subplots(self):
  841. df = DataFrame(np.random.rand(10, 3),
  842. index=list(string.ascii_letters[:10]))
  843. for kind in ['bar', 'barh', 'line', 'area']:
  844. axes = df.plot(kind=kind, subplots=True, sharex=True, legend=True)
  845. self._check_axes_shape(axes, axes_num=3, layout=(3, 1))
  846. for ax, column in zip(axes, df.columns):
  847. self._check_legend_labels(ax, labels=[com.pprint_thing(column)])
  848. for ax in axes[:-2]:
  849. self._check_visible(ax.get_xticklabels(), visible=False)
  850. self._check_visible(ax.get_yticklabels())
  851. self._check_visible(axes[-1].get_xticklabels())
  852. self._check_visible(axes[-1].get_yticklabels())
  853. axes = df.plot(kind=kind, subplots=True, sharex=False)
  854. for ax in axes:
  855. self._check_visible(ax.get_xticklabels())
  856. self._check_visible(ax.get_yticklabels())
  857. axes = df.plot(kind=kind, subplots=True, legend=False)
  858. for ax in axes:
  859. self.assertTrue(ax.get_legend() is None)
  860. def test_negative_log(self):
  861. df = - DataFrame(rand(6, 4),
  862. index=list(string.ascii_letters[:6]),
  863. columns=['x', 'y', 'z', 'four'])
  864. with tm.assertRaises(ValueError):
  865. df.plot(kind='area', logy=True)
  866. with tm.assertRaises(ValueError):
  867. df.plot(kind='area', loglog=True)
  868. def _compare_stacked_y_cood(self, normal_lines, stacked_lines):
  869. base = np.zeros(len(normal_lines[0].get_data()[1]))
  870. for nl, sl in zip(normal_lines, stacked_lines):
  871. base += nl.get_data()[1] # get y coodinates
  872. sy = sl.get_data()[1]
  873. self.assert_numpy_array_equal(base, sy)
  874. def test_line_area_stacked(self):
  875. with tm.RNGContext(42):
  876. df = DataFrame(rand(6, 4),
  877. columns=['w', 'x', 'y', 'z'])
  878. neg_df = - df
  879. # each column has either positive or negative value
  880. sep_df = DataFrame({'w': rand(6), 'x': rand(6),
  881. 'y': - rand(6), 'z': - rand(6)})
  882. # each column has positive-negative mixed value
  883. mixed_df = DataFrame(randn(6, 4), index=list(string.ascii_letters[:6]),
  884. columns=['w', 'x', 'y', 'z'])
  885. for kind in ['line', 'area']:
  886. ax1 = _check_plot_works(df.plot, kind=kind, stacked=False)
  887. ax2 = _check_plot_works(df.plot, kind=kind, stacked=True)
  888. self._compare_stacked_y_cood(ax1.lines, ax2.lines)
  889. ax1 = _check_plot_works(neg_df.plot, kind=kind, stacked=False)
  890. ax2 = _check_plot_works(neg_df.plot, kind=kind, stacked=True)
  891. self._compare_stacked_y_cood(ax1.lines, ax2.lines)
  892. ax1 = _check_plot_works(sep_df.plot, kind=kind, stacked=False)
  893. ax2 = _check_plot_works(sep_df.plot, kind=kind, stacked=True)
  894. self._compare_stacked_y_cood(ax1.lines[:2], ax2.lines[:2])
  895. self._compare_stacked_y_cood(ax1.lines[2:], ax2.lines[2:])
  896. _check_plot_works(mixed_df.plot, stacked=False)
  897. with tm.assertRaises(ValueError):
  898. mixed_df.plot(stacked=True)
  899. _check_plot_works(df.plot, kind=kind, logx=True, stacked=True)
  900. def test_line_area_nan_df(self):
  901. values1 = [1, 2, np.nan, 3]
  902. values2 = [3, np.nan, 2, 1]
  903. df = DataFrame({'a': values1, 'b': values2})
  904. tdf = DataFrame({'a': values1, 'b': values2}, index=tm.makeDateIndex(k=4))
  905. for d in [df, tdf]:
  906. ax = _check_plot_works(d.plot)
  907. masked1 = ax.lines[0].get_ydata()
  908. masked2 = ax.lines[1].get_ydata()
  909. # remove nan for comparison purpose
  910. self.assert_numpy_array_equal(np.delete(masked1.data, 2), np.array([1, 2, 3]))
  911. self.assert_numpy_array_equal(np.delete(masked2.data, 1), np.array([3, 2, 1]))
  912. self.assert_numpy_array_equal(masked1.mask, np.array([False, False, True, False]))
  913. self.assert_numpy_array_equal(masked2.mask, np.array([False, True, False, False]))
  914. expected1 = np.array([1, 2, 0, 3])
  915. expected2 = np.array([3, 0, 2, 1])
  916. ax = _check_plot_works(d.plot, stacked=True)
  917. self.assert_numpy_array_equal(ax.lines[0].get_ydata(), expected1)
  918. self.assert_numpy_array_equal(ax.lines[1].get_ydata(), expected1 + expected2)
  919. ax = _check_plot_works(d.plot, kind='area')
  920. self.assert_numpy_array_equal(ax.lines[0].get_ydata(), expected1)
  921. self.assert_numpy_array_equal(ax.lines[1].get_ydata(), expected1 + expected2)
  922. ax = _check_plot_works(d.plot, kind='area', stacked=False)
  923. self.assert_numpy_array_equal(ax.lines[0].get_ydata(), expected1)
  924. self.assert_numpy_array_equal(ax.lines[1].get_ydata(), expected2)
  925. def test_line_lim(self):
  926. df = DataFrame(rand(6, 3), columns=['x', 'y', 'z'])
  927. ax = df.plot()
  928. xmin, xmax = ax.get_xlim()
  929. lines = ax.get_lines()
  930. self.assertEqual(xmin, lines[0].get_data()[0][0])
  931. self.assertEqual(xmax, lines[0].get_data()[0][-1])
  932. ax = df.plot(secondary_y=True)
  933. xmin, xmax = ax.get_xlim()
  934. lines = ax.get_lines()
  935. self.assertEqual(xmin, lines[0].get_data()[0][0])
  936. self.assertEqual(xmax, lines[0].get_data()[0][-1])
  937. axes = df.plot(secondary_y=True, subplots=True)
  938. for ax in axes:
  939. xmin, xmax = ax.get_xlim()
  940. lines = ax.get_lines()
  941. self.assertEqual(xmin, lines[0].get_data()[0][0])
  942. self.assertEqual(xmax, lines[0].get_data()[0][-1])
  943. def test_area_lim(self):
  944. df = DataFrame(rand(6, 4),
  945. columns=['x', 'y', 'z', 'four'])
  946. neg_df = - df
  947. for stacked in [True, False]:
  948. ax = _check_plot_works(df.plot, kind='area', stacked=stacked)
  949. xmin, xmax = ax.get_xlim()
  950. ymin, ymax = ax.get_ylim()
  951. lines = ax.get_lines()
  952. self.assertEqual(xmin, lines[0].get_data()[0][0])
  953. self.assertEqual(xmax, lines[0].get_data()[0][-1])
  954. self.assertEqual(ymin, 0)
  955. ax = _check_plot_works(neg_df.plot, kind='area', stacked=stacked)
  956. ymin, ymax = ax.get_ylim()
  957. self.assertEqual(ymax, 0)
  958. @slow
  959. def test_bar_colors(self):
  960. import matplotlib.pyplot as plt
  961. default_colors = plt.rcParams.get('axes.color_cycle')
  962. df = DataFrame(randn(5, 5))
  963. ax = df.plot(kind='bar')
  964. self._check_colors(ax.patches[::5], facecolors=default_colors[:5])
  965. tm.close()
  966. custom_colors = 'rgcby'
  967. ax = df.plot(kind='bar', color=custom_colors)
  968. self._check_colors(ax.patches[::5], facecolors=custom_colors)
  969. tm.close()
  970. from matplotlib import cm
  971. # Test str -> colormap functionality
  972. ax = df.plot(kind='bar', colormap='jet')
  973. rgba_colors = lmap(cm.jet, np.linspace(0, 1, 5))
  974. self._check_colors(ax.patches[::5], facecolors=rgba_colors)
  975. tm.close()
  976. # Test colormap functionality
  977. ax = df.plot(kind='bar', colormap=cm.jet)
  978. rgba_colors = lmap(cm.jet, np.linspace(0, 1, 5))
  979. self._check_colors(ax.patches[::5], facecolors=rgba_colors)
  980. tm.close()
  981. ax = df.ix[:, [0]].plot(kind='bar', color='DodgerBlue')
  982. self._check_colors([ax.patches[0]], facecolors=['DodgerBlue'])
  983. @slow
  984. def test_bar_linewidth(self):
  985. df = DataFrame(randn(5, 5))
  986. # regular
  987. ax = df.plot(kind='bar', linewidth=2)
  988. for r in ax.patches:
  989. self.assertEqual(r.get_linewidth(), 2)
  990. # stacked
  991. ax = df.plot(kind='bar', stacked=True, linewidth=2)
  992. for r in ax.patches:
  993. self.assertEqual(r.get_linewidth(), 2)
  994. # subplots
  995. axes = df.plot(kind='bar', linewidth=2, subplots=True)
  996. self._check_axes_shape(axes, axes_num=5, layout=(5, 1))
  997. for ax in axes:
  998. for r in ax.patches:
  999. self.assertEqual(r.get_linewidth(), 2)
  1000. @slow
  1001. def test_bar_barwidth(self):
  1002. df = DataFrame(randn(5, 5))
  1003. width = 0.9
  1004. # regular
  1005. ax = df.plot(kind='bar', width=width)
  1006. for r in ax.patches:
  1007. self.assertEqual(r.get_width(), width / len(df.columns))
  1008. # stacked
  1009. ax = df.plot(kind='bar', stacked=True, width=width)
  1010. for r in ax.patches:
  1011. self.assertEqual(r.get_width(), width)
  1012. # horizontal regular
  1013. ax = df.plot(kind='barh', width=width)
  1014. for r in ax.patches:
  1015. self.assertEqual(r.get_height(), width / len(df.columns))
  1016. # horizontal stacked
  1017. ax = df.plot(kind='barh', stacked=True, width=width)
  1018. for r in ax.patches:
  1019. self.assertEqual(r.get_height(), width)
  1020. # subplots
  1021. axes = df.plot(kind='bar', width=width, subplots=True)
  1022. for ax in axes:
  1023. for r in ax.patches:
  1024. self.assertEqual(r.get_width(), width)
  1025. # horizontal subplots
  1026. axes = df.plot(kind='barh', width=width, subplots=True)
  1027. for ax in axes:
  1028. for r in ax.patches:
  1029. self.assertEqual(r.get_height(), width)
  1030. @slow
  1031. def test_bar_barwidth_position(self):
  1032. df = DataFrame(randn(5, 5))
  1033. self._check_bar_alignment(df, kind='bar', stacked=False, width=0.9, position=0.2)
  1034. self._check_bar_alignment(df, kind='bar', stacked=True, width=0.9, position=0.2)
  1035. self._check_bar_alignment(df, kind='barh', stacked=False, width=0.9, position=0.2)
  1036. self._check_bar_alignment(df, kind='barh', stacked=True, width=0.9, position=0.2)
  1037. self._check_bar_alignment(df, kind='bar', subplots=True, width=0.9, position=0.2)
  1038. self._check_bar_alignment(df, kind='barh', subplots=True, width=0.9, position=0.2)
  1039. @slow
  1040. def test_bar_bottom_left(self):
  1041. df = DataFrame(rand(5, 5))
  1042. ax = df.plot(kind='bar', stacked=False, bottom=1)
  1043. result = [p.get_y() for p in ax.patches]
  1044. self.assertEqual(result, [1] * 25)
  1045. ax = df.plot(kind='bar', stacked=True, bottom=[-1, -2, -3, -4, -5])
  1046. result = [p.get_y() for p in ax.patches[:5]]
  1047. self.assertEqual(result, [-1, -2, -3, -4, -5])
  1048. ax = df.plot(kind='barh', stacked=False, left=np.array([1, 1, 1, 1, 1]))
  1049. result = [p.get_x() for p in ax.patches]
  1050. self.assertEqual(result, [1] * 25)
  1051. ax = df.plot(kind='barh', stacked=True, left=[1, 2, 3, 4, 5])
  1052. result = [p.get_x() for p in ax.patches[:5]]
  1053. self.assertEqual(result, [1, 2, 3, 4, 5])
  1054. axes = df.plot(kind='bar', subplots=True, bottom=-1)
  1055. for ax in axes:
  1056. result = [p.get_y() for p in ax.patches]
  1057. self.assertEqual(result, [-1] * 5)
  1058. axes = df.plot(kind='barh', subplots=True, left=np.array([1, 1, 1, 1, 1]))
  1059. for ax in axes:
  1060. result = [p.get_x() for p in ax.patches]
  1061. self.assertEqual(result, [1] * 5)
  1062. @slow
  1063. def test_plot_scatter(self):
  1064. df = DataFrame(randn(6, 4),
  1065. index=list(string.ascii_letters[:6]),
  1066. columns=['x', 'y', 'z', 'four'])
  1067. _check_plot_works(df.plot, x='x', y='y', kind='scatter')
  1068. _check_plot_works(df.plot, x=1, y=2, kind='scatter')
  1069. with tm.assertRaises(ValueError):
  1070. df.plot(x='x', kind='scatter')
  1071. with tm.assertRaises(ValueError):
  1072. df.plot(y='y', kind='scatter')
  1073. # GH 6951
  1074. axes = df.plot(x='x', y='y', kind='scatter', subplots=True)
  1075. self._check_axes_shape(axes, axes_num=1, layout=(1, 1))
  1076. @slow
  1077. def test_plot_bar(self):
  1078. df = DataFrame(randn(6, 4),
  1079. index=list(string.ascii_letters[:6]),
  1080. columns=['one', 'two', 'three', 'four'])
  1081. _check_plot_works(df.plot, kind='bar')
  1082. _check_plot_works(df.plot, kind='bar', legend=False)
  1083. _check_plot_works(df.plot, kind='bar', subplots=True)
  1084. _check_plot_works(df.plot, kind='bar', stacked=True)
  1085. df = DataFrame(randn(10, 15),
  1086. index=list(string.ascii_letters[:10]),
  1087. columns=lrange(15))
  1088. _check_plot_works(df.plot, kind='bar')
  1089. df = DataFrame({'a': [0, 1], 'b': [1, 0]})
  1090. _check_plot_works(df.plot, kind='bar')
  1091. def _check_bar_alignment(self, df, kind='bar', stacked=False,
  1092. subplots=False, align='center',
  1093. width=0.5, position=0.5):
  1094. axes = df.plot(kind=kind, stacked=stacked, subplots=subplots,
  1095. align=align, width=width, position=position,
  1096. grid=True)
  1097. axes = self._flatten_visible(axes)
  1098. for ax in axes:
  1099. if kind == 'bar':
  1100. axis = ax.xaxis
  1101. ax_min, ax_max = ax.get_xlim()
  1102. min_edge = min([p.get_x() for p in ax.patches])
  1103. max_edge = max([p.get_x() + p.get_width() for p in ax.patches])
  1104. elif kind == 'barh':
  1105. axis = ax.yaxis
  1106. ax_min, ax_max = ax.get_ylim()
  1107. min_edge = min([p.get_y() for p in ax.patches])
  1108. max_edge = max([p.get_y() + p.get_height() for p in ax.patches])
  1109. else:
  1110. raise ValueError
  1111. # GH 7498
  1112. # compare margins between lim and bar edges
  1113. self.assertAlmostEqual(ax_min, min_edge - 0.25)
  1114. self.assertAlmostEqual(ax_max, max_edge + 0.25)
  1115. p = ax.patches[0]
  1116. if kind == 'bar' and (stacked is True or subplots is True):
  1117. edge = p.get_x()
  1118. center = edge + p.get_width() * position
  1119. elif kind == 'bar' and stacked is False:
  1120. center = p.get_x() + p.get_width() * len(df.columns) * position
  1121. edge = p.get_x()
  1122. elif kind == 'barh' and (stacked is True or subplots is True):
  1123. center = p.get_y() + p.get_height() * position
  1124. edge = p.get_y()
  1125. elif kind == 'barh' and stacked is False:
  1126. center = p.get_y() + p.get_height() * len(df.columns) * position
  1127. edge = p.get_y()
  1128. else:
  1129. raise ValueError
  1130. # Check the ticks locates on integer
  1131. self.assertTrue((axis.get_ticklocs() == np.arange(len(df))).all())
  1132. if align == 'center':
  1133. # Check whether the bar locates on center
  1134. self.assertAlmostEqual(axis.get_ticklocs()[0], center)
  1135. elif align == 'edge':
  1136. # Check whether the bar's edge starts from the tick
  1137. self.assertAlmostEqual(axis.get_ticklocs()[0], edge)
  1138. else:
  1139. raise ValueError
  1140. return axes
  1141. @slow
  1142. def test_bar_stacked_center(self):
  1143. # GH2157
  1144. df = DataFrame({'A': [3] * 5, 'B': lrange(5)}, index=lrange(5))
  1145. self._check_bar_alignment(df, kind='bar', stacked=True)
  1146. self._check_bar_alignment(df, kind='bar', stacked=True, width=0.9)
  1147. self._check_bar_alignment(df, kind='barh', stacked=True)
  1148. self._check_bar_alignment(df, kind='barh', stacked=True, width=0.9)
  1149. @slow
  1150. def test_bar_center(self):
  1151. df = DataFrame({'A': [3] * 5, 'B': lrange(5)}, index=lrange(5))
  1152. self._check_bar_alignment(df, kind='bar', stacked=False)
  1153. self._check_bar_alignment(df, kind='bar', stacked=False, width=0.9)
  1154. self._check_bar_alignment(df, kind='barh', stacked=False)
  1155. self._check_bar_alignment(df, kind='barh', stacked=False, width=0.9)
  1156. @slow
  1157. def test_bar_subplots_center(self):
  1158. df = DataFrame({'A': [3] * 5, 'B': lrange(5)}, index=lrange(5))
  1159. self._check_bar_alignment(df, kind='bar', subplots=True)
  1160. self._check_bar_alignment(df, kind='bar', subplots=True, width=0.9)
  1161. self._check_bar_alignment(df, kind='barh', subplots=True)
  1162. self._check_bar_alignment(df, kind='barh', subplots=True, width=0.9)
  1163. @slow
  1164. def test_bar_align_single_column(self):
  1165. df = DataFrame(randn(5))
  1166. self._check_bar_alignment(df, kind='bar', stacked=False)
  1167. self._check_bar_alignment(df, kind='bar', stacked=True)
  1168. self._check_bar_alignment(df, kind='barh', stacked=False)
  1169. self._check_bar_alignment(df, kind='barh', stacked=True)
  1170. self._check_bar_alignment(df, kind='bar', subplots=True)
  1171. self._check_bar_alignment(df, kind='barh', subplots=True)
  1172. @slow
  1173. def test_bar_edge(self):
  1174. df = DataFrame({'A': [3] * 5, 'B': lrange(5)}, index=lrange(5))
  1175. self._check_bar_alignment(df, kind='bar', stacked=True, align='edge')
  1176. self._check_bar_alignment(df, kind='bar', stacked=True,
  1177. width=0.9, align='edge')
  1178. self._check_bar_alignment(df, kind='barh', stacked=True, align='edge')
  1179. self._check_bar_alignment(df, kind='barh', stacked=True,
  1180. width=0.9, align='edge')
  1181. self._check_bar_alignment(df, kind='bar', stacked=False, align='edge')
  1182. self._check_bar_alignment(df, kind='bar', stacked=False,
  1183. width=0.9, align='edge')
  1184. self._check_bar_alignment(df, kind='barh', stacked=False, align='edge')
  1185. self._check_bar_alignment(df, kind='barh', stacked=False,
  1186. width=0.9, align='edge')
  1187. self._check_bar_alignment(df, kind='bar', subplots=True, align='edge')
  1188. self._check_bar_alignment(df, kind='bar', subplots=True,
  1189. width=0.9, align='edge')
  1190. self._check_bar_alignment(df, kind='barh', subplots=True, align='edge')
  1191. self._check_bar_alignment(df, kind='barh', subplots=True,
  1192. width=0.9, align='edge')
  1193. @slow
  1194. def test_bar_log_no_subplots(self):
  1195. # GH3254, GH3298 matplotlib/matplotlib#1882, #1892
  1196. # regressions in 1.2.1
  1197. expected = np.array([1., 10.])
  1198. if not self.mpl_le_1_2_1:
  1199. expected = np.hstack((.1, expected, 100))
  1200. # no subplots
  1201. df = DataFrame({'A': [3] * 5, 'B': lrange(1, 6)}, index=lrange(5))
  1202. ax = df.plot(kind='bar', grid=True, log=True)
  1203. assert_array_equal(ax.yaxis.get_ticklocs(), expected)
  1204. @slow
  1205. def test_bar_log_subplots(self):
  1206. expected = np.array([1., 10., 100., 1000.])
  1207. if not self.mpl_le_1_2_1:
  1208. expected = np.hstack((.1, expected, 1e4))
  1209. ax = DataFrame([Series([200, 300]),
  1210. Series([300, 500])]).plot(log=True, kind='bar',
  1211. subplots=True)
  1212. assert_array_equal(ax[0].yaxis.get_ticklocs(), expected)
  1213. assert_array_equal(ax[1].yaxis.get_ticklocs(), expected)
  1214. @slow
  1215. def test_boxplot(self):
  1216. df = DataFrame(randn(6, 4),
  1217. index=list(string.ascii_letters[:6]),
  1218. columns=['one', 'two', 'three', 'four'])
  1219. df['indic'] = ['foo', 'bar'] * 3
  1220. df['indic2'] = ['foo', 'bar', 'foo'] * 2
  1221. _check_plot_works(df.boxplot, return_type='dict')
  1222. _check_plot_works(df.boxplot, column=['one', 'two'], return_type='dict')
  1223. _check_plot_works(df.boxplot, column=['one', 'two'], by='indic')
  1224. _check_plot_works(df.boxplot, column='one', by=['indic', 'indic2'])
  1225. _check_plot_works(df.boxplot, by='indic')
  1226. _check_plot_works(df.boxplot, by=['indic', 'indic2'])
  1227. _check_plot_works(plotting.boxplot, df['one'], return_type='dict')
  1228. _check_plot_works(df.boxplot, notch=1, return_type='dict')
  1229. _check_plot_works(df.boxplot, by='indic', notch=1)
  1230. df = DataFrame(np.random.rand(10, 2), columns=['Col1', 'Col2'])
  1231. df['X'] = Series(['A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'B'])
  1232. df['Y'] = Series(['A'] * 10)
  1233. _check_plot_works(df.boxplot, by='X')
  1234. # When ax is supplied and required number of axes is 1,
  1235. # passed ax should be used:
  1236. fig, ax = self.plt.subplots()
  1237. axes = df.boxplot('Col1', by='X', ax=ax)
  1238. self.assertIs(ax.get_axes(), axes)
  1239. fig, ax = self.plt.subplots()
  1240. axes = df.groupby('Y').boxplot(ax=ax, return_type='axes')
  1241. self.assertIs(ax.get_axes(), axes['A'])
  1242. # Multiple columns with an ax argument should use same figure
  1243. fig, ax = self.plt.subplots()
  1244. axes = df.boxplot(column=['Col1', 'Col2'], by='X', ax=ax, return_type='axes')
  1245. self.assertIs(axes['Col1'].get_figure(), fig)
  1246. # When by is None, check that all relevant lines are present in the dict
  1247. fig, ax = self.plt.subplots()
  1248. d = df.boxplot(ax=ax, return_type='dict')
  1249. lines = list(itertools.chain.from_iterable(d.values()))
  1250. self.assertEqual(len(ax.get_lines()), len(lines))
  1251. @slow
  1252. def test_boxplot_return_type(self):
  1253. # API change in https://github.com/pydata/pandas/pull/7096
  1254. import matplotlib as mpl
  1255. df = DataFrame(randn(6, 4),
  1256. index=list(string.ascii_letters[:6]),
  1257. columns=['one', 'two', 'three', 'four'])
  1258. with tm.assertRaises(ValueError):
  1259. df.boxplot(return_type='NOTATYPE')
  1260. with tm.assert_produces_warning(FutureWarning):
  1261. result = df.boxplot()
  1262. # change to Axes in future
  1263. self._check_box_return_type(result, 'dict')
  1264. with tm.assert_produces_warning(False):
  1265. result = df.boxplot(return_type='dict')
  1266. self._check_box_return_type(result, 'dict')
  1267. with tm.assert_produces_warning(False):
  1268. result = df.boxplot(return_type='axes')
  1269. self._check_box_return_type(result, 'axes')
  1270. with tm.assert_produces_warning(False):
  1271. result = df.boxplot(return_type='both')
  1272. self._check_box_return_type(result, 'both')
  1273. @slow
  1274. def test_kde(self):
  1275. tm._skip_if_no_scipy()
  1276. _skip_if_no_scipy_gaussian_kde()
  1277. df = DataFrame(randn(100, 4))
  1278. ax = _check_plot_works(df.plot, kind='kde')
  1279. expected = [com.pprint_thing(c) for c in df.columns]
  1280. self._check_legend_labels(ax, labels=expected)
  1281. axes = _check_plot_works(df.plot, kind='kde', subplots=True)
  1282. self._check_axes_shape(axes, axes_num=4, layout=(4, 1))
  1283. axes = df.plot(kind='kde', logy=True, subplots=True)
  1284. self._check_ax_scales(axes, yaxis='log')
  1285. @slow
  1286. def test_hist(self):
  1287. _check_plot_works(self.hist_df.hist)
  1288. # make sure layout is handled
  1289. df = DataFrame(randn(100, 3))
  1290. axes = _check_plot_works(df.hist, grid=False)
  1291. self._check_axes_shape(axes, axes_num=3, layout=(2, 2))
  1292. self.assertFalse(axes[1, 1].get_visible())
  1293. df = DataFrame(randn(100, 1))
  1294. _check_plot_works(df.hist)
  1295. # make sure layout is handled
  1296. df = DataFrame(randn(100, 6))
  1297. axes = _check_plot_works(df.hist, layout=(4, 2))
  1298. self._check_axes_shape(axes, axes_num=6, layout=(4, 2))
  1299. # make sure sharex, sharey is handled
  1300. _check_plot_works(df.hist, sharex=True, sharey=True)
  1301. # handle figsize arg
  1302. _check_plot_works(df.hist, figsize=(8, 10))
  1303. # check bins argument
  1304. _check_plot_works(df.hist, bins=5)
  1305. # make sure xlabelsize and xrot are handled
  1306. ser = df[0]
  1307. xf, yf = 20, 18
  1308. xrot, yrot = 30, 40
  1309. axes = ser.hist(xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot)
  1310. self._check_ticks_props(axes, xlabelsize=xf, xrot=xrot,
  1311. ylabelsize=yf, yrot=yrot)
  1312. xf, yf = 20, 18
  1313. xrot, yrot = 30, 40
  1314. axes = df.hist(xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot)
  1315. self._check_ticks_props(axes, xlabelsize=xf, xrot=xrot,
  1316. ylabelsize=yf, yrot=yrot)
  1317. tm.close()
  1318. # make sure kwargs to hist are handled
  1319. ax = ser.hist(normed=True, cumulative=True, bins=4)
  1320. # height of last bin (index 5) must be 1.0
  1321. self.assertAlmostEqual(ax.get_children()[5].get_height(), 1.0)
  1322. tm.close()
  1323. ax = ser.hist(log=True)
  1324. # scale of y must be 'log'
  1325. self._check_ax_scales(ax, yaxis='log')
  1326. tm.close()
  1327. # propagate attr exception from matplotlib.Axes.hist
  1328. with tm.assertRaises(AttributeError):
  1329. ser.hist(foo='bar')
  1330. @slow
  1331. def test_hist_layout(self):
  1332. df = DataFrame(randn(100, 3))
  1333. layout_to_expected_size = (
  1334. {'layout': None, 'expected_size': (2, 2)}, # default is 2x2
  1335. {'layout': (2, 2), 'expected_size': (2, 2)},
  1336. {'layout': (4, 1), 'expected_size': (4, 1)},
  1337. {'layout': (1, 4), 'expected_size': (1, 4)},
  1338. {'layout': (3, 3), 'expected_size': (3, 3)},
  1339. )
  1340. for layout_test in layout_to_expected_size:
  1341. axes = df.hist(layout=layout_test['layout'])
  1342. expected = layout_test['expected_size']
  1343. self._check_axes_shape(axes, axes_num=3, layout=expected)
  1344. # layout too small for all 4 plots
  1345. with tm.assertRaises(ValueError):
  1346. df.hist(layout=(1, 1))
  1347. # invalid format for layout
  1348. with tm.assertRaises(ValueError):
  1349. df.hist(layout=(1,))
  1350. @slow
  1351. def test_scatter(self):
  1352. tm._skip_if_no_scipy()
  1353. df = DataFrame(randn(100, 2))
  1354. import pandas.tools.plotting as plt
  1355. def scat(**kwds):
  1356. return plt.scatter_matrix(df, **kwds)
  1357. _check_plot_works(scat)
  1358. _check_plot_works(scat, marker='+')
  1359. _check_plot_works(scat, vmin=0)
  1360. if _ok_for_gaussian_kde('kde'):
  1361. _check_plot_works(scat, diagonal='kde')
  1362. if _ok_for_gaussian_kde('density'):
  1363. _check_plot_works(scat, diagonal='density')
  1364. _check_plot_works(scat, diagonal='hist')
  1365. _check_plot_works(scat, range_padding=.1)
  1366. def scat2(x, y, by=None, ax=None, figsize=None):
  1367. return plt.scatter_plot(df, x, y, by, ax, figsize=None)
  1368. _check_plot_works(scat2, 0, 1)
  1369. grouper = Series(np.repeat([1, 2, 3, 4, 5], 20), df.index)
  1370. _check_plot_works(scat2, 0, 1, by=grouper)
  1371. @slow
  1372. def test_andrews_curves(self):
  1373. from pandas.tools.plotting import andrews_curves
  1374. from matplotlib import cm
  1375. df = self.iris
  1376. _check_plot_works(andrews_curves, df, 'Name')
  1377. rgba = ('#556270', '#4ECDC4', '#C7F464')
  1378. ax = _check_plot_works(andrews_curves, df, 'Name', color=rgba)
  1379. self._check_colors(ax.get_lines()[:10], linecolors=rgba, mapping=df['Name'][:10])
  1380. cnames = ['dodgerblue', 'aquamarine', 'seagreen']
  1381. ax = _check_plot_works(andrews_curves, df, 'Name', color=cnames)
  1382. self._check_colors(ax.get_lines()[:10], linecolors=cnames, mapping=df['Name'][:10])
  1383. ax = _check_plot_works(andrews_curves, df, 'Name', colormap=cm.jet)
  1384. cmaps = lmap(cm.jet, np.linspace(0, 1, df['Name'].nunique()))
  1385. self._check_colors(ax.get_lines()[:10], linecolors=cmaps, mapping=df['Name'][:10])
  1386. colors = ['b', 'g', 'r']
  1387. df = DataFrame({"A": [1, 2, 3],
  1388. "B": [1, 2, 3],
  1389. "C": [1, 2, 3],
  1390. "Name": colors})
  1391. ax = andrews_curves(df, 'Name', color=colors)
  1392. handles, labels = ax.get_legend_handles_labels()
  1393. self._check_colors(handles, linecolors=colors)
  1394. with tm.assert_produces_warning(FutureWarning):
  1395. andrews_curves(data=df, class_column='Name')
  1396. @slow
  1397. def test_parallel_coordinates(self):
  1398. from pandas.tools.plotting import parallel_coordinates
  1399. from matplotlib import cm
  1400. df = self.iris
  1401. _check_plot_works(parallel_coordinates, df, 'Name')
  1402. rgba = ('#556270', '#4ECDC4', '#C7F464')
  1403. ax = _check_plot_works(parallel_coordinates, df, 'Name', color=rgba)
  1404. self._check_colors(ax.get_lines()[:10], linecolors=rgba, mapping=df['Name'][:10])
  1405. cnames = ['dodgerblue', 'aquamarine', 'seagreen']
  1406. ax = _check_plot_works(parallel_coordinates, df, 'Name', color=cnames)
  1407. self._check_colors(ax.get_lines()[:10], linecolors=cnames, mapping=df['Name'][:10])
  1408. ax = _check_plot_works(parallel_coordinates, df, 'Name', colormap=cm.jet)
  1409. cmaps = lmap(cm.jet, np.linspace(0, 1, df['Name'].nunique()))
  1410. self._check_colors(ax.get_lines()[:10], linecolors=cmaps, mapping=df['Name'][:10])
  1411. colors = ['b', 'g', 'r']
  1412. df = DataFrame({"A": [1, 2, 3],
  1413. "B": [1, 2, 3],
  1414. "C": [1, 2, 3],
  1415. "Name": colors})
  1416. ax = parallel_coordinates(df, 'Name', color=colors)
  1417. handles, labels = ax.get_legend_handles_labels()
  1418. self._check_colors(handles, linecolors=colors)
  1419. with tm.assert_produces_warning(FutureWarning):
  1420. parallel_coordinates(data=df, class_column='Name')
  1421. with tm.assert_produces_warning(FutureWarning):
  1422. parallel_coordinates(df, 'Name', colors=colors)
  1423. @slow
  1424. def test_radviz(self):
  1425. from pandas.tools.plotting import radviz
  1426. from matplotlib import cm
  1427. df = self.iris
  1428. _check_plot_works(radviz, df, 'Name')
  1429. rgba = ('#556270', '#4ECDC4', '#C7F464')
  1430. ax = _check_plot_works(radviz, df, 'Name', color=rgba)
  1431. # skip Circle drawn as ticks
  1432. patches = [p for p in ax.patches[:20] if p.get_label() != '']
  1433. self._check_colors(patches[:10], facecolors=rgba, mapping=df['Name'][:10])
  1434. cnames = ['dodgerblue', 'aquamarine', 'seagreen']
  1435. _check_plot_works(radviz, df, 'Name', color=cnames)
  1436. patches = [p for p in ax.patches[:20] if p.get_label() != '']
  1437. self._check_colors(patches, facecolors=cnames, mapping=df['Name'][:10])
  1438. _check_plot_works(radviz, df, 'Name', colormap=cm.jet)
  1439. cmaps = lmap(cm.jet, np.linspace(0, 1, df['Name'].nunique()))
  1440. patches = [p for p in ax.patches[:20] if p.get_label() != '']
  1441. self._check_colors(patches, facecolors=cmaps, mapping=df['Name'][:10])
  1442. colors = [[0., 0., 1., 1.],
  1443. [0., 0.5, 1., 1.],
  1444. [1., 0., 0., 1.]]
  1445. df = DataFrame({"A": [1, 2, 3],
  1446. "B": [2, 1, 3],
  1447. "C": [3, 2, 1],
  1448. "Name": ['b', 'g', 'r']})
  1449. ax = radviz(df, 'Name', color=colors)
  1450. handles, labels = ax.get_legend_handles_labels()
  1451. self._check_colors(handles, facecolors=colors)
  1452. @slow
  1453. def test_plot_int_columns(self):
  1454. df = DataFrame(randn(100, 4)).cumsum()
  1455. _check_plot_works(df.plot, legend=True)
  1456. @slow
  1457. def test_df_legend_labels(self):
  1458. kinds = 'line', 'bar', 'barh', 'kde', 'area'
  1459. df = DataFrame(rand(3, 3), columns=['a', 'b', 'c'])
  1460. df2 = DataFrame(rand(3, 3), columns=['d', 'e', 'f'])
  1461. df3 = DataFrame(rand(3, 3), columns=['g', 'h', 'i'])
  1462. df4 = DataFrame(rand(3, 3), columns=['j', 'k', 'l'])
  1463. for kind in kinds:
  1464. if not _ok_for_gaussian_kde(kind):
  1465. continue
  1466. ax = df.plot(kind=kind, legend=True)
  1467. self._check_legend_labels(ax, labels=df.columns)
  1468. ax = df2.plot(kind=kind, legend=False, ax=ax)
  1469. self._check_legend_labels(ax, labels=df.columns)
  1470. ax = df3.plot(kind=kind, legend=True, ax=ax)
  1471. self._check_legend_labels(ax, labels=df.columns + df3.columns)
  1472. ax = df4.plot(kind=kind, legend='reverse', ax=ax)
  1473. expected = list(df.columns + df3.columns) + list(reversed(df4.columns))
  1474. self._check_legend_labels(ax, labels=expected)
  1475. # Secondary Y
  1476. ax = df.plot(legend=True, secondary_y='b')
  1477. self._check_legend_labels(ax, labels=['a', 'b (right)', 'c'])
  1478. ax = df2.plot(legend=False, ax=ax)
  1479. self._check_legend_labels(ax, labels=['a', 'b (right)', 'c'])
  1480. ax = df3.plot(kind='bar', legend=True, secondary_y='h', ax=ax)
  1481. self._check_legend_labels(ax, labels=['a', 'b (right)', 'c', 'g', 'h (right)', 'i'])
  1482. # Time Series
  1483. ind = date_range('1/1/2014', periods=3)
  1484. df = DataFrame(randn(3, 3), columns=['a', 'b', 'c'], index=ind)
  1485. df2 = DataFrame(randn(3, 3), columns=['d', 'e', 'f'], index=ind)
  1486. df3 = DataFrame(randn(3, 3), columns=['g', 'h', 'i'], index=ind)
  1487. ax = df.plot(legend=True, secondary_y='b')
  1488. self._check_legend_labels(ax, labels=['a', 'b (right)', 'c'])
  1489. ax = df2.plot(legend=False, ax=ax)
  1490. self._check_legend_labels(ax, labels=['a', 'b (right)', 'c'])
  1491. ax = df3.plot(legend=True, ax=ax)
  1492. self._check_legend_labels(ax, labels=['a', 'b (right)', 'c', 'g', 'h', 'i'])
  1493. # scatter
  1494. ax = df.plot(kind='scatter', x='a', y='b', label='data1')
  1495. self._check_legend_labels(ax, labels=['data1'])
  1496. ax = df2.plot(kind='scatter', x='d', y='e', legend=False,
  1497. label='data2', ax=ax)
  1498. self._check_legend_labels(ax, labels=['data1'])
  1499. ax = df3.plot(kind='scatter', x='g', y='h', label='data3', ax=ax)
  1500. self._check_legend_labels(ax, labels=['data1', 'data3'])
  1501. def test_legend_name(self):
  1502. multi = DataFrame(randn(4, 4),
  1503. columns=[np.array(['a', 'a', 'b', 'b']),
  1504. np.array(['x', 'y', 'x', 'y'])])
  1505. multi.columns.names = ['group', 'individual']
  1506. ax = multi.plot()
  1507. leg_title = ax.legend_.get_title()
  1508. self._check_text_labels(leg_title, 'group,individual')
  1509. df = DataFrame(randn(5, 5))
  1510. ax = df.plot(legend=True, ax=ax)
  1511. leg_title = ax.legend_.get_title()
  1512. self._check_text_labels(leg_title, 'group,individual')
  1513. df.columns.name = 'new'
  1514. ax = df.plot(legend=False, ax=ax)
  1515. leg_title = ax.legend_.get_title()
  1516. self._check_text_labels(leg_title, 'group,individual')
  1517. ax = df.plot(legend=True, ax=ax)
  1518. leg_title = ax.legend_.get_title()
  1519. self._check_text_labels(leg_title, 'new')
  1520. @slow
  1521. def test_no_legend(self):
  1522. kinds = 'line', 'bar', 'barh', 'kde', 'area'
  1523. df = DataFrame(rand(3, 3), columns=['a', 'b', 'c'])
  1524. for kind in kinds:
  1525. if not _ok_for_gaussian_kde(kind):
  1526. continue
  1527. ax = df.plot(kind=kind, legend=False)
  1528. self._check_legend_labels(ax, visible=False)
  1529. @slow
  1530. def test_style_by_column(self):
  1531. import matplotlib.pyplot as plt
  1532. fig = plt.gcf()
  1533. df = DataFrame(randn(100, 3))
  1534. for markers in [{0: '^', 1: '+', 2: 'o'},
  1535. {0: '^', 1: '+'},
  1536. ['^', '+', 'o'],
  1537. ['^', '+']]:
  1538. fig.clf()
  1539. fig.add_subplot(111)
  1540. ax = df.plot(style=markers)
  1541. for i, l in enumerate(ax.get_lines()[:len(markers)]):
  1542. self.assertEqual(l.get_marker(), markers[i])
  1543. @slow
  1544. def test_line_colors(self):
  1545. import sys
  1546. from matplotlib import cm
  1547. custom_colors = 'rgcby'
  1548. df = DataFrame(randn(5, 5))
  1549. ax = df.plot(color=custom_colors)
  1550. self._check_colors(ax.get_lines(), linecolors=custom_colors)
  1551. tmp = sys.stderr
  1552. sys.stderr = StringIO()
  1553. try:
  1554. tm.close()
  1555. ax2 = df.plot(colors=custom_colors)
  1556. lines2 = ax2.get_lines()
  1557. for l1, l2 in zip(ax.get_lines(), lines2):
  1558. self.assertEqual(l1.get_color(), l2.get_color())
  1559. finally:
  1560. sys.stderr = tmp
  1561. tm.close()
  1562. ax = df.plot(colormap='jet')
  1563. rgba_colors = lmap(cm.jet, np.linspace(0, 1, len(df)))
  1564. self._check_colors(ax.get_lines(), linecolors=rgba_colors)
  1565. tm.close()
  1566. ax = df.plot(colormap=cm.jet)
  1567. rgba_colors = lmap(cm.jet, np.linspace(0, 1, len(df)))
  1568. self._check_colors(ax.get_lines(), linecolors=rgba_colors)
  1569. tm.close()
  1570. # make color a list if plotting one column frame
  1571. # handles cases like df.plot(color='DodgerBlue')
  1572. ax = df.ix[:, [0]].plot(color='DodgerBlue')
  1573. self._check_colors(ax.lines, linecolors=['DodgerBlue'])
  1574. @slow
  1575. def test_area_colors(self):
  1576. from matplotlib import cm
  1577. from matplotlib.collections import PolyCollection
  1578. custom_colors = 'rgcby'
  1579. df = DataFrame(rand(5, 5))
  1580. ax = df.plot(kind='area', color=custom_colors)
  1581. self._check_colors(ax.get_lines(), linecolors=custom_colors)
  1582. poly = [o for o in ax.get_children() if isinstance(o, PolyCollection)]
  1583. self._check_colors(poly, facecolors=custom_colors)
  1584. tm.close()
  1585. ax = df.plot(kind='area', colormap='jet')
  1586. rgba_colors = lmap(cm.jet, np.linspace(0, 1, len(df)))
  1587. self._check_colors(ax.get_lines(), linecolors=rgba_colors)
  1588. poly = [o for o in ax.get_children() if isinstance(o, PolyCollection)]
  1589. self._check_colors(poly, facecolors=rgba_colors)
  1590. tm.close()
  1591. ax = df.plot(kind='area', colormap=cm.jet)
  1592. rgba_colors = lmap(cm.jet, np.linspace(0, 1, len(df)))
  1593. self._check_colors(ax.get_lines(), linecolors=rgba_colors)
  1594. poly = [o for o in ax.get_children() if isinstance(o, PolyCollection)]
  1595. self._check_colors(poly, facecolors=rgba_colors)
  1596. def test_default_color_cycle(self):
  1597. import matplotlib.pyplot as plt
  1598. plt.rcParams['axes.color_cycle'] = list('rgbk')
  1599. df = DataFrame(randn(5, 3))
  1600. ax = df.plot()
  1601. expected = plt.rcParams['axes.color_cycle'][:3]
  1602. self._check_colors(ax.get_lines(), linecolors=expected)
  1603. def test_unordered_ts(self):
  1604. df = DataFrame(np.array([3.0, 2.0, 1.0]),
  1605. index=[date(2012, 10, 1),
  1606. date(2012, 9, 1),
  1607. date(2012, 8, 1)],
  1608. columns=['test'])
  1609. ax = df.plot()
  1610. xticks = ax.lines[0].get_xdata()
  1611. self.assertTrue(xticks[0] < xticks[1])
  1612. ydata = ax.lines[0].get_ydata()
  1613. assert_array_equal(ydata, np.array([1.0, 2.0, 3.0]))
  1614. def test_all_invalid_plot_data(self):
  1615. df = DataFrame(list('abcd'))
  1616. for kind in plotting._common_kinds:
  1617. if not _ok_for_gaussian_kde(kind):
  1618. continue
  1619. with tm.assertRaises(TypeError):
  1620. df.plot(kind=kind)
  1621. @slow
  1622. def test_partially_invalid_plot_data(self):
  1623. with tm.RNGContext(42):
  1624. df = DataFrame(randn(10, 2), dtype=object)
  1625. df[np.random.rand(df.shape[0]) > 0.5] = 'a'
  1626. for kind in plotting._common_kinds:
  1627. if not _ok_for_gaussian_kde(kind):
  1628. continue
  1629. with tm.assertRaises(TypeError):
  1630. df.plot(kind=kind)
  1631. with tm.RNGContext(42):
  1632. # area plot doesn't support positive/negative mixed data
  1633. kinds = ['area']
  1634. df = DataFrame(rand(10, 2), dtype=object)
  1635. df[np.random.rand(df.shape[0]) > 0.5] = 'a'
  1636. for kind in kinds:
  1637. with tm.assertRaises(TypeError):
  1638. df.plot(kind=kind)
  1639. def test_invalid_kind(self):
  1640. df = DataFrame(randn(10, 2))
  1641. with tm.assertRaises(ValueError):
  1642. df.plot(kind='aasdf')
  1643. @slow
  1644. def test_hexbin_basic(self):
  1645. df = self.hexbin_df
  1646. ax = df.plot(kind='hexbin', x='A', y='B', gridsize=10)
  1647. # TODO: need better way to test. This just does existence.
  1648. self.assertEqual(len(ax.collections), 1)
  1649. # GH 6951
  1650. axes = df.plot(x='A', y='B', kind='hexbin', subplots=True)
  1651. # hexbin should have 2 axes in the figure, 1 for plotting and another is colorbar
  1652. self.assertEqual(len(axes[0].figure.axes), 2)
  1653. # return value is single axes
  1654. self._check_axes_shape(axes, axes_num=1, layout=(1, 1))
  1655. @slow
  1656. def test_hexbin_with_c(self):
  1657. df = self.hexbin_df
  1658. ax = df.plot(kind='hexbin', x='A', y='B', C='C')
  1659. self.assertEqual(len(ax.collections), 1)
  1660. ax = df.plot(kind='hexbin', x='A', y='B', C='C',
  1661. reduce_C_function=np.std)
  1662. self.assertEqual(len(ax.collections), 1)
  1663. @slow
  1664. def test_hexbin_cmap(self):
  1665. df = self.hexbin_df
  1666. # Default to BuGn
  1667. ax = df.plot(kind='hexbin', x='A', y='B')
  1668. self.assertEqual(ax.collections[0].cmap.name, 'BuGn')
  1669. cm = 'cubehelix'
  1670. ax = df.plot(kind='hexbin', x='A', y='B', colormap=cm)
  1671. self.assertEqual(ax.collections[0].cmap.name, cm)
  1672. @slow
  1673. def test_no_color_bar(self):
  1674. df = self.hexbin_df
  1675. ax = df.plot(kind='hexbin', x='A', y='B', colorbar=None)
  1676. self.assertIs(ax.collections[0].colorbar, None)
  1677. @slow
  1678. def test_allow_cmap(self):
  1679. df = self.hexbin_df
  1680. ax = df.plot(kind='hexbin', x='A', y='B', cmap='YlGn')
  1681. self.assertEqual(ax.collections[0].cmap.name, 'YlGn')
  1682. with tm.assertRaises(TypeError):
  1683. df.plot(kind='hexbin', x='A', y='B', cmap='YlGn',
  1684. colormap='BuGn')
  1685. @slow
  1686. def test_pie_df(self):
  1687. df = DataFrame(np.random.rand(5, 3), columns=['X', 'Y', 'Z'],
  1688. index=['a', 'b', 'c', 'd', 'e'])
  1689. with tm.assertRaises(ValueError):
  1690. df.plot(kind='pie')
  1691. ax = _check_plot_works(df.plot, kind='pie', y='Y')
  1692. self._check_text_labels(ax.texts, df.index)
  1693. axes = _check_plot_works(df.plot, kind='pie', subplots=True)
  1694. self.assertEqual(len(axes), len(df.columns))
  1695. for ax in axes:
  1696. self._check_text_labels(ax.texts, df.index)
  1697. for ax, ylabel in zip(axes, df.columns):
  1698. self.assertEqual(ax.get_ylabel(), ylabel)
  1699. labels = ['A', 'B', 'C', 'D', 'E']
  1700. color_args = ['r', 'g', 'b', 'c', 'm']
  1701. axes = _check_plot_works(df.plot, kind='pie', subplots=True,
  1702. labels=labels, colors=color_args)
  1703. self.assertEqual(len(axes), len(df.columns))
  1704. for ax in axes:
  1705. self._check_text_labels(ax.texts, labels)
  1706. self._check_colors(ax.patches, facecolors=color_args)
  1707. def test_errorbar_plot(self):
  1708. d = {'x': np.arange(12), 'y': np.arange(12, 0, -1)}
  1709. df = DataFrame(d)
  1710. d_err = {'x': np.ones(12)*0.2, 'y': np.ones(12)*0.4}
  1711. df_err = DataFrame(d_err)
  1712. # check line plots
  1713. ax = _check_plot_works(df.plot, yerr=df_err, logy=True)
  1714. self._check_has_errorbars(ax, xerr=0, yerr=2)
  1715. ax = _check_plot_works(df.plot, yerr=df_err, logx=True, logy=True)
  1716. self._check_has_errorbars(ax, xerr=0, yerr=2)
  1717. ax = _check_plot_works(df.plot, yerr=df_err, loglog=True)
  1718. self._check_has_errorbars(ax, xerr=0, yerr=2)
  1719. kinds = ['line', 'bar', 'barh']
  1720. for kind in kinds:
  1721. ax = _check_plot_works(df.plot, yerr=df_err['x'], kind=kind)
  1722. self._check_has_errorbars(ax, xerr=0, yerr=2)
  1723. ax = _check_plot_works(df.plot, yerr=d_err, kind=kind)
  1724. self._check_has_errorbars(ax, xerr=0, yerr=2)
  1725. ax = _check_plot_works(df.plot, yerr=df_err, xerr=df_err, kind=kind)
  1726. self._check_has_errorbars(ax, xerr=2, yerr=2)
  1727. ax = _check_plot_works(df.plot, yerr=df_err['x'], xerr=df_err['x'], kind=kind)
  1728. self._check_has_errorbars(ax, xerr=2, yerr=2)
  1729. ax = _check_plot_works(df.plot, xerr=0.2, yerr=0.2, kind=kind)
  1730. self._check_has_errorbars(ax, xerr=2, yerr=2)
  1731. axes = _check_plot_works(df.plot, yerr=df_err, xerr=df_err, subplots=True, kind=kind)
  1732. self._check_has_errorbars(axes, xerr=1, yerr=1)
  1733. ax = _check_plot_works((df+1).plot, yerr=df_err, xerr=df_err, kind='bar', log=True)
  1734. self._check_has_errorbars(ax, xerr=2, yerr=2)
  1735. # yerr is raw error values
  1736. ax = _check_plot_works(df['y'].plot, yerr=np.ones(12)*0.4)
  1737. self._check_has_errorbars(ax, xerr=0, yerr=1)
  1738. ax = _check_plot_works(df.plot, yerr=np.ones((2, 12))*0.4)
  1739. self._check_has_errorbars(ax, xerr=0, yerr=2)
  1740. # yerr is iterator
  1741. import itertools
  1742. ax = _check_plot_works(df.plot, yerr=itertools.repeat(0.1, len(df)))
  1743. self._check_has_errorbars(ax, xerr=0, yerr=2)
  1744. # yerr is column name
  1745. for yerr in ['yerr', u('誤塎')]:
  1746. s_df = df.copy()
  1747. s_df[yerr] = np.ones(12)*0.2
  1748. ax = _check_plot_works(s_df.plot, yerr=yerr)
  1749. self._check_has_errorbars(ax, xerr=0, yerr=2)
  1750. ax = _check_plot_works(s_df.plot, y='y', x='x', yerr=yerr)
  1751. self._check_has_errorbars(ax, xerr=0, yerr=1)
  1752. with tm.assertRaises(ValueError):
  1753. df.plot(yerr=np.random.randn(11))
  1754. df_err = DataFrame({'x': ['zzz']*12, 'y': ['zzz']*12})
  1755. with tm.assertRaises(TypeError):
  1756. df.plot(yerr=df_err)
  1757. @slow
  1758. def test_errorbar_with_integer_column_names(self):
  1759. # test with integer column names
  1760. df = DataFrame(np.random.randn(10, 2))
  1761. df_err = DataFrame(np.random.randn(10, 2))
  1762. ax = _check_plot_works(df.plot, yerr=df_err)
  1763. self._check_has_errorbars(ax, xerr=0, yerr=2)
  1764. ax = _check_plot_works(df.plot, y=0, yerr=1)
  1765. self._check_has_errorbars(ax, xerr=0, yerr=1)
  1766. @slow
  1767. def test_errorbar_with_partial_columns(self):
  1768. df = DataFrame(np.random.randn(10, 3))
  1769. df_err = DataFrame(np.random.randn(10, 2), columns=[0, 2])
  1770. kinds = ['line', 'bar']
  1771. for kind in kinds:
  1772. ax = _check_plot_works(df.plot, yerr=df_err, kind=kind)
  1773. self._check_has_errorbars(ax, xerr=0, yerr=2)
  1774. ix = date_range('1/1/2000', periods=10, freq='M')
  1775. df.set_index(ix, inplace=True)
  1776. df_err.set_index(ix, inplace=True)
  1777. ax = _check_plot_works(df.plot, yerr=df_err, kind='line')
  1778. self._check_has_errorbars(ax, xerr=0, yerr=2)
  1779. d = {'x': np.arange(12), 'y': np.arange(12, 0, -1)}
  1780. df = DataFrame(d)
  1781. d_err = {'x': np.ones(12)*0.2, 'z': np.ones(12)*0.4}
  1782. df_err = DataFrame(d_err)
  1783. for err in [d_err, df_err]:
  1784. ax = _check_plot_works(df.plot, yerr=err)
  1785. self._check_has_errorbars(ax, xerr=0, yerr=1)
  1786. @slow
  1787. def test_errorbar_timeseries(self):
  1788. d = {'x': np.arange(12), 'y': np.arange(12, 0, -1)}
  1789. d_err = {'x': np.ones(12)*0.2, 'y': np.ones(12)*0.4}
  1790. # check time-series plots
  1791. ix = date_range('1/1/2000', '1/1/2001', freq='M')
  1792. tdf = DataFrame(d, index=ix)
  1793. tdf_err = DataFrame(d_err, index=ix)
  1794. kinds = ['line', 'bar', 'barh']
  1795. for kind in kinds:
  1796. ax = _check_plot_works(tdf.plot, yerr=tdf_err, kind=kind)
  1797. self._check_has_errorbars(ax, xerr=0, yerr=2)
  1798. ax = _check_plot_works(tdf.plot, yerr=d_err, kind=kind)
  1799. self._check_has_errorbars(ax, xerr=0, yerr=2)
  1800. ax = _check_plot_works(tdf.plot, y='y', yerr=tdf_err['x'], kind=kind)
  1801. self._check_has_errorbars(ax, xerr=0, yerr=1)
  1802. ax = _check_plot_works(tdf.plot, y='y', yerr='x', kind=kind)
  1803. self._check_has_errorbars(ax, xerr=0, yerr=1)
  1804. ax = _check_plot_works(tdf.plot, yerr=tdf_err, kind=kind)
  1805. self._check_has_errorbars(ax, xerr=0, yerr=2)
  1806. axes = _check_plot_works(tdf.plot, kind=kind, yerr=tdf_err, subplots=True)
  1807. self._check_has_errorbars(axes, xerr=0, yerr=1)
  1808. def test_errorbar_asymmetrical(self):
  1809. np.random.seed(0)
  1810. err = np.random.rand(3, 2, 5)
  1811. data = np.random.randn(5, 3)
  1812. df = DataFrame(data)
  1813. ax = df.plot(yerr=err, xerr=err/2)
  1814. self.assertEqual(ax.lines[7].get_ydata()[0], data[0,1]-err[1,0,0])
  1815. self.assertEqual(ax.lines[8].get_ydata()[0], data[0,1]+err[1,1,0])
  1816. self.assertEqual(ax.lines[5].get_xdata()[0], -err[1,0,0]/2)
  1817. self.assertEqual(ax.lines[6].get_xdata()[0], err[1,1,0]/2)
  1818. with tm.assertRaises(ValueError):
  1819. df.plot(yerr=err.T)
  1820. tm.close()
  1821. def test_table(self):
  1822. df = DataFrame(np.random.rand(10, 3),
  1823. index=list(string.ascii_letters[:10]))
  1824. _check_plot_works(df.plot, table=True)
  1825. _check_plot_works(df.plot, table=df)
  1826. ax = df.plot()
  1827. self.assertTrue(len(ax.tables) == 0)
  1828. plotting.table(ax, df.T)
  1829. self.assertTrue(len(ax.tables) == 1)
  1830. def test_errorbar_scatter(self):
  1831. df = DataFrame(np.random.randn(5, 2), index=range(5), columns=['x', 'y'])
  1832. df_err = DataFrame(np.random.randn(5, 2) / 5,
  1833. index=range(5), columns=['x', 'y'])
  1834. ax = _check_plot_works(df.plot, kind='scatter', x='x', y='y')
  1835. self._check_has_errorbars(ax, xerr=0, yerr=0)
  1836. ax = _check_plot_works(df.plot, kind='scatter', x='x', y='y', xerr=df_err)
  1837. self._check_has_errorbars(ax, xerr=1, yerr=0)
  1838. ax = _check_plot_works(df.plot, kind='scatter', x='x', y='y', yerr=df_err)
  1839. self._check_has_errorbars(ax, xerr=0, yerr=1)
  1840. ax = _check_plot_works(df.plot, kind='scatter', x='x', y='y',
  1841. xerr=df_err, yerr=df_err)
  1842. self._check_has_errorbars(ax, xerr=1, yerr=1)
  1843. @tm.mplskip
  1844. class TestDataFrameGroupByPlots(TestPlotBase):
  1845. @slow
  1846. def test_boxplot(self):
  1847. grouped = self.hist_df.groupby(by='gender')
  1848. axes = _check_plot_works(grouped.boxplot, return_type='axes')
  1849. self._check_axes_shape(axes.values(), axes_num=2, layout=(1, 2))
  1850. axes = _check_plot_works(grouped.boxplot, subplots=False,
  1851. return_type='axes')
  1852. self._check_axes_shape(axes, axes_num=1, layout=(1, 1))
  1853. tuples = lzip(string.ascii_letters[:10], range(10))
  1854. df = DataFrame(np.random.rand(10, 3),
  1855. index=MultiIndex.from_tuples(tuples))
  1856. grouped = df.groupby(level=1)
  1857. axes = _check_plot_works(grouped.boxplot, return_type='axes')
  1858. self._check_axes_shape(axes.values(), axes_num=10, layout=(4, 3))
  1859. axes = _check_plot_works(grouped.boxplot, subplots=False,
  1860. return_type='axes')
  1861. self._check_axes_shape(axes, axes_num=1, layout=(1, 1))
  1862. grouped = df.unstack(level=1).groupby(level=0, axis=1)
  1863. axes = _check_plot_works(grouped.boxplot, return_type='axes')
  1864. self._check_axes_shape(axes.values(), axes_num=3, layout=(2, 2))
  1865. axes = _check_plot_works(grouped.boxplot, subplots=False,
  1866. return_type='axes')
  1867. self._check_axes_shape(axes, axes_num=1, layout=(1, 1))
  1868. def test_series_plot_color_kwargs(self):
  1869. # GH1890
  1870. ax = Series(np.arange(12) + 1).plot(color='green')
  1871. self._check_colors(ax.get_lines(), linecolors=['green'])
  1872. def test_time_series_plot_color_kwargs(self):
  1873. # #1890
  1874. ax = Series(np.arange(12) + 1, index=date_range(
  1875. '1/1/2000', periods=12)).plot(color='green')
  1876. self._check_colors(ax.get_lines(), linecolors=['green'])
  1877. def test_time_series_plot_color_with_empty_kwargs(self):
  1878. import matplotlib as mpl
  1879. def_colors = mpl.rcParams['axes.color_cycle']
  1880. index = date_range('1/1/2000', periods=12)
  1881. s = Series(np.arange(1, 13), index=index)
  1882. ncolors = 3
  1883. for i in range(ncolors):
  1884. ax = s.plot()
  1885. self._check_colors(ax.get_lines(), linecolors=def_colors[:ncolors])
  1886. @slow
  1887. def test_grouped_hist(self):
  1888. df = DataFrame(randn(500, 2), columns=['A', 'B'])
  1889. df['C'] = np.random.randint(0, 4, 500)
  1890. df['D'] = ['X'] * 500
  1891. axes = plotting.grouped_hist(df.A, by=df.C)
  1892. self._check_axes_shape(axes, axes_num=4, layout=(2, 2))
  1893. tm.close()
  1894. axes = df.hist(by=df.C)
  1895. self._check_axes_shape(axes, axes_num=4, layout=(2, 2))
  1896. tm.close()
  1897. # group by a key with single value
  1898. axes = df.hist(by='D', rot=30)
  1899. self._check_axes_shape(axes, axes_num=1, layout=(1, 1))
  1900. self._check_ticks_props(axes, xrot=30)
  1901. tm.close()
  1902. # make sure kwargs to hist are handled
  1903. xf, yf = 20, 18
  1904. xrot, yrot = 30, 40
  1905. axes = plotting.grouped_hist(df.A, by=df.C, normed=True,
  1906. cumulative=True, bins=4,
  1907. xlabelsize=xf, xrot=xrot, ylabelsize=yf, yrot=yrot)
  1908. # height of last bin (index 5) must be 1.0
  1909. for ax in axes.ravel():
  1910. height = ax.get_children()[5].get_height()
  1911. self.assertAlmostEqual(height, 1.0)
  1912. self._check_ticks_props(axes, xlabelsize=xf, xrot=xrot,
  1913. ylabelsize=yf, yrot=yrot)
  1914. tm.close()
  1915. axes = plotting.grouped_hist(df.A, by=df.C, log=True)
  1916. # scale of y must be 'log'
  1917. self._check_ax_scales(axes, yaxis='log')
  1918. tm.close()
  1919. # propagate attr exception from matplotlib.Axes.hist
  1920. with tm.assertRaises(AttributeError):
  1921. plotting.grouped_hist(df.A, by=df.C, foo='bar')
  1922. with tm.assert_produces_warning(FutureWarning):
  1923. df.hist(by='C', figsize='default')
  1924. @slow
  1925. def test_grouped_box_return_type(self):
  1926. df = self.hist_df
  1927. # old style: return_type=None
  1928. result = df.boxplot(by='gender')
  1929. self.assertIsInstance(result, np.ndarray)
  1930. self._check_box_return_type(result, None,
  1931. expected_keys=['height', 'weight', 'category'])
  1932. # now for groupby
  1933. with tm.assert_produces_warning(FutureWarning):
  1934. result = df.groupby('gender').boxplot()
  1935. self._check_box_return_type(result, 'dict', expected_keys=['Male', 'Female'])
  1936. columns2 = 'X B C D A G Y N Q O'.split()
  1937. df2 = DataFrame(random.randn(50, 10), columns=columns2)
  1938. categories2 = 'A B C D E F G H I J'.split()
  1939. df2['category'] = categories2 * 5
  1940. for t in ['dict', 'axes', 'both']:
  1941. returned = df.groupby('classroom').boxplot(return_type=t)
  1942. self._check_box_return_type(returned, t, expected_keys=['A', 'B', 'C'])
  1943. returned = df.boxplot(by='classroom', return_type=t)
  1944. self._check_box_return_type(returned, t,
  1945. expected_keys=['height', 'weight', 'category'])
  1946. returned = df2.groupby('category').boxplot(return_type=t)
  1947. self._check_box_return_type(returned, t, expected_keys=categories2)
  1948. returned = df2.boxplot(by='category', return_type=t)
  1949. self._check_box_return_type(returned, t, expected_keys=columns2)
  1950. @slow
  1951. def test_grouped_box_layout(self):
  1952. df = self.hist_df
  1953. self.assertRaises(ValueError, df.boxplot, column=['weight', 'height'],
  1954. by=df.gender, layout=(1, 1))
  1955. self.assertRaises(ValueError, df.boxplot, column=['height', 'weight', 'category'],
  1956. layout=(2, 1), return_type='dict')
  1957. box = _check_plot_works(df.groupby('gender').boxplot, column='height',
  1958. return_type='dict')
  1959. self._check_axes_shape(self.plt.gcf().axes, axes_num=2, layout=(1, 2))
  1960. box = _check_plot_works(df.groupby('category').boxplot, column='height',
  1961. return_type='dict')
  1962. self._check_axes_shape(self.plt.gcf().axes, axes_num=4, layout=(2, 2))
  1963. # GH 6769
  1964. box = _check_plot_works(df.groupby('classroom').boxplot,
  1965. column='height', return_type='dict')
  1966. self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(2, 2))
  1967. # GH 5897
  1968. axes = df.boxplot(column=['height', 'weight', 'category'], by='gender',
  1969. return_type='axes')
  1970. self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(2, 2))
  1971. for ax in [axes['height']]:
  1972. self._check_visible(ax.get_xticklabels(), visible=False)
  1973. self._check_visible([ax.xaxis.get_label()], visible=False)
  1974. for ax in [axes['weight'], axes['category']]:
  1975. self._check_visible(ax.get_xticklabels())
  1976. self._check_visible([ax.xaxis.get_label()])
  1977. box = df.groupby('classroom').boxplot(
  1978. column=['height', 'weight', 'category'], return_type='dict')
  1979. self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(2, 2))
  1980. box = _check_plot_works(df.groupby('category').boxplot, column='height',
  1981. layout=(3, 2), return_type='dict')
  1982. self._check_axes_shape(self.plt.gcf().axes, axes_num=4, layout=(3, 2))
  1983. box = df.boxplot(column=['height', 'weight', 'category'], by='gender', layout=(4, 1))
  1984. self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(4, 1))
  1985. box = df.groupby('classroom').boxplot(
  1986. column=['height', 'weight', 'category'], layout=(1, 4),
  1987. return_type='dict')
  1988. self._check_axes_shape(self.plt.gcf().axes, axes_num=3, layout=(1, 4))
  1989. @slow
  1990. def test_grouped_hist_layout(self):
  1991. df = self.hist_df
  1992. self.assertRaises(ValueError, df.hist, column='weight', by=df.gender,
  1993. layout=(1, 1))
  1994. self.assertRaises(ValueError, df.hist, column='height', by=df.category,
  1995. layout=(1, 3))
  1996. axes = _check_plot_works(df.hist, column='height', by=df.gender, layout=(2, 1))
  1997. self._check_axes_shape(axes, axes_num=2, layout=(2, 1))
  1998. axes = _check_plot_works(df.hist, column='height', by=df.category, layout=(4, 1))
  1999. self._check_axes_shape(axes, axes_num=4, layout=(4, 1))
  2000. axes = _check_plot_works(df.hist, column='height', by=df.category,
  2001. layout=(4, 2), figsize=(12, 8))
  2002. self._check_axes_shape(axes, axes_num=4, layout=(4, 2), figsize=(12, 8))
  2003. # GH 6769
  2004. axes = _check_plot_works(df.hist, column='height', by='classroom', layout=(2, 2))
  2005. self._check_axes_shape(axes, axes_num=3, layout=(2, 2))
  2006. # without column
  2007. axes = _check_plot_works(df.hist, by='classroom')
  2008. self._check_axes_shape(axes, axes_num=3, layout=(2, 2))
  2009. axes = _check_plot_works(df.hist, by='gender', layout=(3, 5))
  2010. self._check_axes_shape(axes, axes_num=2, layout=(3, 5))
  2011. axes = _check_plot_works(df.hist, column=['height', 'weight', 'category'])
  2012. self._check_axes_shape(axes, axes_num=3, layout=(2, 2))
  2013. @slow
  2014. def test_axis_share_x(self):
  2015. df = self.hist_df
  2016. # GH4089
  2017. ax1, ax2 = df.hist(column='height', by=df.gender, sharex=True)
  2018. # share x
  2019. self.assertTrue(ax1._shared_x_axes.joined(ax1, ax2))
  2020. self.assertTrue(ax2._shared_x_axes.joined(ax1, ax2))
  2021. # don't share y
  2022. self.assertFalse(ax1._shared_y_axes.joined(ax1, ax2))
  2023. self.assertFalse(ax2._shared_y_axes.joined(ax1, ax2))
  2024. @slow
  2025. def test_axis_share_y(self):
  2026. df = self.hist_df
  2027. ax1, ax2 = df.hist(column='height', by=df.gender, sharey=True)
  2028. # share y
  2029. self.assertTrue(ax1._shared_y_axes.joined(ax1, ax2))
  2030. self.assertTrue(ax2._shared_y_axes.joined(ax1, ax2))
  2031. # don't share x
  2032. self.assertFalse(ax1._shared_x_axes.joined(ax1, ax2))
  2033. self.assertFalse(ax2._shared_x_axes.joined(ax1, ax2))
  2034. @slow
  2035. def test_axis_share_xy(self):
  2036. df = self.hist_df
  2037. ax1, ax2 = df.hist(column='height', by=df.gender, sharex=True,
  2038. sharey=True)
  2039. # share both x and y
  2040. self.assertTrue(ax1._shared_x_axes.joined(ax1, ax2))
  2041. self.assertTrue(ax2._shared_x_axes.joined(ax1, ax2))
  2042. self.assertTrue(ax1._shared_y_axes.joined(ax1, ax2))
  2043. self.assertTrue(ax2._shared_y_axes.joined(ax1, ax2))
  2044. def test_option_mpl_style(self):
  2045. set_option('display.mpl_style', 'default')
  2046. set_option('display.mpl_style', None)
  2047. set_option('display.mpl_style', False)
  2048. with tm.assertRaises(ValueError):
  2049. set_option('display.mpl_style', 'default2')
  2050. def test_invalid_colormap(self):
  2051. df = DataFrame(randn(3, 2), columns=['A', 'B'])
  2052. with tm.assertRaises(ValueError):
  2053. df.plot(colormap='invalid_colormap')
  2054. def assert_is_valid_plot_return_object(objs):
  2055. import matplotlib.pyplot as plt
  2056. if isinstance(objs, np.ndarray):
  2057. for el in objs.flat:
  2058. assert isinstance(el, plt.Axes), ('one of \'objs\' is not a '
  2059. 'matplotlib Axes instance, '
  2060. 'type encountered {0!r}'
  2061. ''.format(el.__class__.__name__))
  2062. else:
  2063. assert isinstance(objs, (plt.Artist, tuple, dict)), \
  2064. ('objs is neither an ndarray of Artist instances nor a '
  2065. 'single Artist instance, tuple, or dict, "objs" is a {0!r} '
  2066. ''.format(objs.__class__.__name__))
  2067. def _check_plot_works(f, *args, **kwargs):
  2068. import matplotlib.pyplot as plt
  2069. ret = None
  2070. try:
  2071. try:
  2072. fig = kwargs['figure']
  2073. except KeyError:
  2074. fig = plt.gcf()
  2075. plt.clf()
  2076. ax = kwargs.get('ax', fig.add_subplot(211))
  2077. ret = f(*args, **kwargs)
  2078. assert_is_valid_plot_return_object(ret)
  2079. try:
  2080. kwargs['ax'] = fig.add_subplot(212)
  2081. ret = f(*args, **kwargs)
  2082. except Exception:
  2083. pass
  2084. else:
  2085. assert_is_valid_plot_return_object(ret)
  2086. with ensure_clean(return_filelike=True) as path:
  2087. plt.savefig(path)
  2088. finally:
  2089. tm.close(fig)
  2090. return ret
  2091. def curpath():
  2092. pth, _ = os.path.split(os.path.abspath(__file__))
  2093. return pth
  2094. if __name__ == '__main__':
  2095. nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],
  2096. exit=False)