PageRenderTime 57ms CodeModel.GetById 13ms 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

Large files files are truncated, but you can click here to view the full file

  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

Large files files are truncated, but you can click here to view the full file