PageRenderTime 57ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/pandas/tseries/tests/test_plotting.py

http://github.com/pydata/pandas
Python | 1045 lines | 851 code | 162 blank | 32 comment | 60 complexity | 52c5509bbb066255a19b6b1f8d314a55 MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0
  1. from datetime import datetime, timedelta, date, time
  2. import nose
  3. from pandas.compat import lrange, zip
  4. import numpy as np
  5. from numpy.testing.decorators import slow
  6. from numpy.testing import assert_array_equal
  7. from pandas import Index, Series, DataFrame
  8. from pandas.tseries.index import date_range, bdate_range
  9. from pandas.tseries.offsets import DateOffset
  10. from pandas.tseries.period import period_range, Period, PeriodIndex
  11. from pandas.tseries.resample import DatetimeIndex
  12. from pandas.util.testing import assert_series_equal, ensure_clean
  13. import pandas.util.testing as tm
  14. from pandas.tests.test_graphics import _skip_if_no_scipy_gaussian_kde
  15. @tm.mplskip
  16. class TestTSPlot(tm.TestCase):
  17. def setUp(self):
  18. freq = ['S', 'T', 'H', 'D', 'W', 'M', 'Q', 'Y']
  19. idx = [period_range('12/31/1999', freq=x, periods=100) for x in freq]
  20. self.period_ser = [Series(np.random.randn(len(x)), x) for x in idx]
  21. self.period_df = [DataFrame(np.random.randn(len(x), 3), index=x,
  22. columns=['A', 'B', 'C'])
  23. for x in idx]
  24. freq = ['S', 'T', 'H', 'D', 'W', 'M', 'Q-DEC', 'A', '1B30Min']
  25. idx = [date_range('12/31/1999', freq=x, periods=100) for x in freq]
  26. self.datetime_ser = [Series(np.random.randn(len(x)), x) for x in idx]
  27. self.datetime_df = [DataFrame(np.random.randn(len(x), 3), index=x,
  28. columns=['A', 'B', 'C'])
  29. for x in idx]
  30. def tearDown(self):
  31. tm.close()
  32. @slow
  33. def test_ts_plot_with_tz(self):
  34. # GH2877
  35. index = date_range('1/1/2011', periods=2, freq='H',
  36. tz='Europe/Brussels')
  37. ts = Series([188.5, 328.25], index=index)
  38. _check_plot_works(ts.plot)
  39. @slow
  40. def test_frame_inferred(self):
  41. # inferred freq
  42. import matplotlib.pyplot as plt
  43. idx = date_range('1/1/1987', freq='MS', periods=100)
  44. idx = DatetimeIndex(idx.values, freq=None)
  45. df = DataFrame(np.random.randn(len(idx), 3), index=idx)
  46. _check_plot_works(df.plot)
  47. # axes freq
  48. idx = idx[0:40] + idx[45:99]
  49. df2 = DataFrame(np.random.randn(len(idx), 3), index=idx)
  50. _check_plot_works(df2.plot)
  51. # N > 1
  52. idx = date_range('2008-1-1 00:15:00', freq='15T', periods=10)
  53. idx = DatetimeIndex(idx.values, freq=None)
  54. df = DataFrame(np.random.randn(len(idx), 3), index=idx)
  55. _check_plot_works(df.plot)
  56. def test_nonnumeric_exclude(self):
  57. import matplotlib.pyplot as plt
  58. idx = date_range('1/1/1987', freq='A', periods=3)
  59. df = DataFrame({'A': ["x", "y", "z"], 'B': [1,2,3]}, idx)
  60. ax = df.plot() # it works
  61. self.assertEqual(len(ax.get_lines()), 1) #B was plotted
  62. plt.close(plt.gcf())
  63. self.assertRaises(TypeError, df['A'].plot)
  64. @slow
  65. def test_tsplot(self):
  66. from pandas.tseries.plotting import tsplot
  67. import matplotlib.pyplot as plt
  68. ax = plt.gca()
  69. ts = tm.makeTimeSeries()
  70. f = lambda *args, **kwds: tsplot(s, plt.Axes.plot, *args, **kwds)
  71. for s in self.period_ser:
  72. _check_plot_works(f, s.index.freq, ax=ax, series=s)
  73. for s in self.datetime_ser:
  74. _check_plot_works(f, s.index.freq.rule_code, ax=ax, series=s)
  75. ax = ts.plot(style='k')
  76. self.assertEqual((0., 0., 0.), ax.get_lines()[0].get_color())
  77. def test_both_style_and_color(self):
  78. import matplotlib.pyplot as plt
  79. ts = tm.makeTimeSeries()
  80. self.assertRaises(ValueError, ts.plot, style='b-', color='#000099')
  81. s = ts.reset_index(drop=True)
  82. self.assertRaises(ValueError, s.plot, style='b-', color='#000099')
  83. @slow
  84. def test_high_freq(self):
  85. freaks = ['ms', 'us']
  86. for freq in freaks:
  87. rng = date_range('1/1/2012', periods=100000, freq=freq)
  88. ser = Series(np.random.randn(len(rng)), rng)
  89. _check_plot_works(ser.plot)
  90. def test_get_datevalue(self):
  91. from pandas.tseries.converter import get_datevalue
  92. self.assertIsNone(get_datevalue(None, 'D'))
  93. self.assertEqual(get_datevalue(1987, 'A'), 1987)
  94. self.assertEqual(get_datevalue(Period(1987, 'A'), 'M'),
  95. Period('1987-12', 'M').ordinal)
  96. self.assertEqual(get_datevalue('1/1/1987', 'D'),
  97. Period('1987-1-1', 'D').ordinal)
  98. @slow
  99. def test_ts_plot_format_coord(self):
  100. def check_format_of_first_point(ax, expected_string):
  101. first_line = ax.get_lines()[0]
  102. first_x = first_line.get_xdata()[0].ordinal
  103. first_y = first_line.get_ydata()[0]
  104. try:
  105. self.assertEqual(expected_string, ax.format_coord(first_x, first_y))
  106. except (ValueError):
  107. raise nose.SkipTest("skipping test because issue forming test comparison GH7664")
  108. annual = Series(1, index=date_range('2014-01-01', periods=3, freq='A-DEC'))
  109. check_format_of_first_point(annual.plot(), 't = 2014 y = 1.000000')
  110. # note this is added to the annual plot already in existence, and changes its freq field
  111. daily = Series(1, index=date_range('2014-01-01', periods=3, freq='D'))
  112. check_format_of_first_point(daily.plot(), 't = 2014-01-01 y = 1.000000')
  113. @slow
  114. def test_line_plot_period_series(self):
  115. for s in self.period_ser:
  116. _check_plot_works(s.plot, s.index.freq)
  117. @slow
  118. def test_line_plot_datetime_series(self):
  119. for s in self.datetime_ser:
  120. _check_plot_works(s.plot, s.index.freq.rule_code)
  121. @slow
  122. def test_line_plot_period_frame(self):
  123. for df in self.period_df:
  124. _check_plot_works(df.plot, df.index.freq)
  125. @slow
  126. def test_line_plot_datetime_frame(self):
  127. for df in self.datetime_df:
  128. freq = df.index.to_period(df.index.freq.rule_code).freq
  129. _check_plot_works(df.plot, freq)
  130. @slow
  131. def test_line_plot_inferred_freq(self):
  132. for ser in self.datetime_ser:
  133. ser = Series(ser.values, Index(np.asarray(ser.index)))
  134. _check_plot_works(ser.plot, ser.index.inferred_freq)
  135. ser = ser[[0, 3, 5, 6]]
  136. _check_plot_works(ser.plot)
  137. def test_fake_inferred_business(self):
  138. import matplotlib.pyplot as plt
  139. fig = plt.gcf()
  140. plt.clf()
  141. fig.add_subplot(111)
  142. rng = date_range('2001-1-1', '2001-1-10')
  143. ts = Series(lrange(len(rng)), rng)
  144. ts = ts[:3].append(ts[5:])
  145. ax = ts.plot()
  146. self.assertFalse(hasattr(ax, 'freq'))
  147. @slow
  148. def test_plot_offset_freq(self):
  149. ser = tm.makeTimeSeries()
  150. _check_plot_works(ser.plot)
  151. dr = date_range(ser.index[0], freq='BQS', periods=10)
  152. ser = Series(np.random.randn(len(dr)), dr)
  153. _check_plot_works(ser.plot)
  154. @slow
  155. def test_plot_multiple_inferred_freq(self):
  156. dr = Index([datetime(2000, 1, 1),
  157. datetime(2000, 1, 6),
  158. datetime(2000, 1, 11)])
  159. ser = Series(np.random.randn(len(dr)), dr)
  160. _check_plot_works(ser.plot)
  161. @slow
  162. def test_uhf(self):
  163. import pandas.tseries.converter as conv
  164. import matplotlib.pyplot as plt
  165. fig = plt.gcf()
  166. plt.clf()
  167. fig.add_subplot(111)
  168. idx = date_range('2012-6-22 21:59:51.960928', freq='L', periods=500)
  169. df = DataFrame(np.random.randn(len(idx), 2), idx)
  170. ax = df.plot()
  171. axis = ax.get_xaxis()
  172. tlocs = axis.get_ticklocs()
  173. tlabels = axis.get_ticklabels()
  174. for loc, label in zip(tlocs, tlabels):
  175. xp = conv._from_ordinal(loc).strftime('%H:%M:%S.%f')
  176. rs = str(label.get_text())
  177. if len(rs):
  178. self.assertEqual(xp, rs)
  179. @slow
  180. def test_irreg_hf(self):
  181. import matplotlib.pyplot as plt
  182. fig = plt.gcf()
  183. plt.clf()
  184. fig.add_subplot(111)
  185. idx = date_range('2012-6-22 21:59:51', freq='S', periods=100)
  186. df = DataFrame(np.random.randn(len(idx), 2), idx)
  187. irreg = df.ix[[0, 1, 3, 4]]
  188. ax = irreg.plot()
  189. diffs = Series(ax.get_lines()[0].get_xydata()[:, 0]).diff()
  190. sec = 1. / 24 / 60 / 60
  191. self.assertTrue((np.fabs(diffs[1:] - [sec, sec * 2, sec]) < 1e-8).all())
  192. plt.clf()
  193. fig.add_subplot(111)
  194. df2 = df.copy()
  195. df2.index = df.index.asobject
  196. ax = df2.plot()
  197. diffs = Series(ax.get_lines()[0].get_xydata()[:, 0]).diff()
  198. self.assertTrue((np.fabs(diffs[1:] - sec) < 1e-8).all())
  199. def test_irregular_datetime64_repr_bug(self):
  200. import matplotlib.pyplot as plt
  201. ser = tm.makeTimeSeries()
  202. ser = ser[[0, 1, 2, 7]]
  203. fig = plt.gcf()
  204. plt.clf()
  205. ax = fig.add_subplot(211)
  206. ret = ser.plot()
  207. self.assertIsNotNone(ret)
  208. for rs, xp in zip(ax.get_lines()[0].get_xdata(), ser.index):
  209. self.assertEqual(rs, xp)
  210. def test_business_freq(self):
  211. import matplotlib.pyplot as plt
  212. bts = tm.makePeriodSeries()
  213. ax = bts.plot()
  214. self.assertEqual(ax.get_lines()[0].get_xydata()[0, 0],
  215. bts.index[0].ordinal)
  216. idx = ax.get_lines()[0].get_xdata()
  217. self.assertEqual(PeriodIndex(data=idx).freqstr, 'B')
  218. @slow
  219. def test_business_freq_convert(self):
  220. n = tm.N
  221. tm.N = 300
  222. bts = tm.makeTimeSeries().asfreq('BM')
  223. tm.N = n
  224. ts = bts.to_period('M')
  225. ax = bts.plot()
  226. self.assertEqual(ax.get_lines()[0].get_xydata()[0, 0],
  227. ts.index[0].ordinal)
  228. idx = ax.get_lines()[0].get_xdata()
  229. self.assertEqual(PeriodIndex(data=idx).freqstr, 'M')
  230. def test_nonzero_base(self):
  231. # GH2571
  232. idx = (date_range('2012-12-20', periods=24, freq='H') +
  233. timedelta(minutes=30))
  234. df = DataFrame(np.arange(24), index=idx)
  235. ax = df.plot()
  236. rs = ax.get_lines()[0].get_xdata()
  237. self.assertFalse(Index(rs).is_normalized)
  238. def test_dataframe(self):
  239. bts = DataFrame({'a': tm.makeTimeSeries()})
  240. ax = bts.plot()
  241. idx = ax.get_lines()[0].get_xdata()
  242. assert_array_equal(bts.index.to_period(), idx)
  243. @slow
  244. def test_axis_limits(self):
  245. import matplotlib.pyplot as plt
  246. def _test(ax):
  247. xlim = ax.get_xlim()
  248. ax.set_xlim(xlim[0] - 5, xlim[1] + 10)
  249. ax.get_figure().canvas.draw()
  250. result = ax.get_xlim()
  251. self.assertEqual(result[0], xlim[0] - 5)
  252. self.assertEqual(result[1], xlim[1] + 10)
  253. # string
  254. expected = (Period('1/1/2000', ax.freq),
  255. Period('4/1/2000', ax.freq))
  256. ax.set_xlim('1/1/2000', '4/1/2000')
  257. ax.get_figure().canvas.draw()
  258. result = ax.get_xlim()
  259. self.assertEqual(int(result[0]), expected[0].ordinal)
  260. self.assertEqual(int(result[1]), expected[1].ordinal)
  261. # datetim
  262. expected = (Period('1/1/2000', ax.freq),
  263. Period('4/1/2000', ax.freq))
  264. ax.set_xlim(datetime(2000, 1, 1), datetime(2000, 4, 1))
  265. ax.get_figure().canvas.draw()
  266. result = ax.get_xlim()
  267. self.assertEqual(int(result[0]), expected[0].ordinal)
  268. self.assertEqual(int(result[1]), expected[1].ordinal)
  269. fig = ax.get_figure()
  270. plt.close(fig)
  271. ser = tm.makeTimeSeries()
  272. ax = ser.plot()
  273. _test(ax)
  274. df = DataFrame({'a': ser, 'b': ser + 1})
  275. ax = df.plot()
  276. _test(ax)
  277. df = DataFrame({'a': ser, 'b': ser + 1})
  278. axes = df.plot(subplots=True)
  279. for ax in axes:
  280. _test(ax)
  281. def test_get_finder(self):
  282. import pandas.tseries.converter as conv
  283. self.assertEqual(conv.get_finder('B'), conv._daily_finder)
  284. self.assertEqual(conv.get_finder('D'), conv._daily_finder)
  285. self.assertEqual(conv.get_finder('M'), conv._monthly_finder)
  286. self.assertEqual(conv.get_finder('Q'), conv._quarterly_finder)
  287. self.assertEqual(conv.get_finder('A'), conv._annual_finder)
  288. self.assertEqual(conv.get_finder('W'), conv._daily_finder)
  289. @slow
  290. def test_finder_daily(self):
  291. import matplotlib.pyplot as plt
  292. xp = Period('1999-1-1', freq='B').ordinal
  293. day_lst = [10, 40, 252, 400, 950, 2750, 10000]
  294. for n in day_lst:
  295. rng = bdate_range('1999-1-1', periods=n)
  296. ser = Series(np.random.randn(len(rng)), rng)
  297. ax = ser.plot()
  298. xaxis = ax.get_xaxis()
  299. rs = xaxis.get_majorticklocs()[0]
  300. self.assertEqual(xp, rs)
  301. vmin, vmax = ax.get_xlim()
  302. ax.set_xlim(vmin + 0.9, vmax)
  303. rs = xaxis.get_majorticklocs()[0]
  304. self.assertEqual(xp, rs)
  305. plt.close(ax.get_figure())
  306. @slow
  307. def test_finder_quarterly(self):
  308. import matplotlib.pyplot as plt
  309. xp = Period('1988Q1').ordinal
  310. yrs = [3.5, 11]
  311. for n in yrs:
  312. rng = period_range('1987Q2', periods=int(n * 4), freq='Q')
  313. ser = Series(np.random.randn(len(rng)), rng)
  314. ax = ser.plot()
  315. xaxis = ax.get_xaxis()
  316. rs = xaxis.get_majorticklocs()[0]
  317. self.assertEqual(rs, xp)
  318. (vmin, vmax) = ax.get_xlim()
  319. ax.set_xlim(vmin + 0.9, vmax)
  320. rs = xaxis.get_majorticklocs()[0]
  321. self.assertEqual(xp, rs)
  322. plt.close(ax.get_figure())
  323. @slow
  324. def test_finder_monthly(self):
  325. import matplotlib.pyplot as plt
  326. xp = Period('Jan 1988').ordinal
  327. yrs = [1.15, 2.5, 4, 11]
  328. for n in yrs:
  329. rng = period_range('1987Q2', periods=int(n * 12), freq='M')
  330. ser = Series(np.random.randn(len(rng)), rng)
  331. ax = ser.plot()
  332. xaxis = ax.get_xaxis()
  333. rs = xaxis.get_majorticklocs()[0]
  334. self.assertEqual(rs, xp)
  335. vmin, vmax = ax.get_xlim()
  336. ax.set_xlim(vmin + 0.9, vmax)
  337. rs = xaxis.get_majorticklocs()[0]
  338. self.assertEqual(xp, rs)
  339. plt.close(ax.get_figure())
  340. def test_finder_monthly_long(self):
  341. rng = period_range('1988Q1', periods=24 * 12, freq='M')
  342. ser = Series(np.random.randn(len(rng)), rng)
  343. ax = ser.plot()
  344. xaxis = ax.get_xaxis()
  345. rs = xaxis.get_majorticklocs()[0]
  346. xp = Period('1989Q1', 'M').ordinal
  347. self.assertEqual(rs, xp)
  348. @slow
  349. def test_finder_annual(self):
  350. import matplotlib.pyplot as plt
  351. xp = [1987, 1988, 1990, 1990, 1995, 2020, 2070, 2170]
  352. for i, nyears in enumerate([5, 10, 19, 49, 99, 199, 599, 1001]):
  353. rng = period_range('1987', periods=nyears, freq='A')
  354. ser = Series(np.random.randn(len(rng)), rng)
  355. ax = ser.plot()
  356. xaxis = ax.get_xaxis()
  357. rs = xaxis.get_majorticklocs()[0]
  358. self.assertEqual(rs, Period(xp[i], freq='A').ordinal)
  359. plt.close(ax.get_figure())
  360. @slow
  361. def test_finder_minutely(self):
  362. nminutes = 50 * 24 * 60
  363. rng = date_range('1/1/1999', freq='Min', periods=nminutes)
  364. ser = Series(np.random.randn(len(rng)), rng)
  365. ax = ser.plot()
  366. xaxis = ax.get_xaxis()
  367. rs = xaxis.get_majorticklocs()[0]
  368. xp = Period('1/1/1999', freq='Min').ordinal
  369. self.assertEqual(rs, xp)
  370. def test_finder_hourly(self):
  371. nhours = 23
  372. rng = date_range('1/1/1999', freq='H', periods=nhours)
  373. ser = Series(np.random.randn(len(rng)), rng)
  374. ax = ser.plot()
  375. xaxis = ax.get_xaxis()
  376. rs = xaxis.get_majorticklocs()[0]
  377. xp = Period('1/1/1999', freq='H').ordinal
  378. self.assertEqual(rs, xp)
  379. @slow
  380. def test_gaps(self):
  381. import matplotlib.pyplot as plt
  382. ts = tm.makeTimeSeries()
  383. ts[5:25] = np.nan
  384. ax = ts.plot()
  385. lines = ax.get_lines()
  386. self.assertEqual(len(lines), 1)
  387. l = lines[0]
  388. data = l.get_xydata()
  389. tm.assert_isinstance(data, np.ma.core.MaskedArray)
  390. mask = data.mask
  391. self.assertTrue(mask[5:25, 1].all())
  392. plt.close(ax.get_figure())
  393. # irregular
  394. ts = tm.makeTimeSeries()
  395. ts = ts[[0, 1, 2, 5, 7, 9, 12, 15, 20]]
  396. ts[2:5] = np.nan
  397. ax = ts.plot()
  398. lines = ax.get_lines()
  399. self.assertEqual(len(lines), 1)
  400. l = lines[0]
  401. data = l.get_xydata()
  402. tm.assert_isinstance(data, np.ma.core.MaskedArray)
  403. mask = data.mask
  404. self.assertTrue(mask[2:5, 1].all())
  405. plt.close(ax.get_figure())
  406. # non-ts
  407. idx = [0, 1, 2, 5, 7, 9, 12, 15, 20]
  408. ser = Series(np.random.randn(len(idx)), idx)
  409. ser[2:5] = np.nan
  410. ax = ser.plot()
  411. lines = ax.get_lines()
  412. self.assertEqual(len(lines), 1)
  413. l = lines[0]
  414. data = l.get_xydata()
  415. tm.assert_isinstance(data, np.ma.core.MaskedArray)
  416. mask = data.mask
  417. self.assertTrue(mask[2:5, 1].all())
  418. @slow
  419. def test_gap_upsample(self):
  420. low = tm.makeTimeSeries()
  421. low[5:25] = np.nan
  422. ax = low.plot()
  423. idxh = date_range(low.index[0], low.index[-1], freq='12h')
  424. s = Series(np.random.randn(len(idxh)), idxh)
  425. s.plot(secondary_y=True)
  426. lines = ax.get_lines()
  427. self.assertEqual(len(lines), 1)
  428. self.assertEqual(len(ax.right_ax.get_lines()), 1)
  429. l = lines[0]
  430. data = l.get_xydata()
  431. tm.assert_isinstance(data, np.ma.core.MaskedArray)
  432. mask = data.mask
  433. self.assertTrue(mask[5:25, 1].all())
  434. @slow
  435. def test_secondary_y(self):
  436. import matplotlib.pyplot as plt
  437. ser = Series(np.random.randn(10))
  438. ser2 = Series(np.random.randn(10))
  439. ax = ser.plot(secondary_y=True).right_ax
  440. fig = ax.get_figure()
  441. axes = fig.get_axes()
  442. l = ax.get_lines()[0]
  443. xp = Series(l.get_ydata(), l.get_xdata())
  444. assert_series_equal(ser, xp)
  445. self.assertEqual(ax.get_yaxis().get_ticks_position(), 'right')
  446. self.assertFalse(axes[0].get_yaxis().get_visible())
  447. plt.close(fig)
  448. ax2 = ser2.plot()
  449. self.assertEqual(ax2.get_yaxis().get_ticks_position(), 'default')
  450. plt.close(ax2.get_figure())
  451. ax = ser2.plot()
  452. ax2 = ser.plot(secondary_y=True).right_ax
  453. self.assertTrue(ax.get_yaxis().get_visible())
  454. @slow
  455. def test_secondary_y_ts(self):
  456. import matplotlib.pyplot as plt
  457. idx = date_range('1/1/2000', periods=10)
  458. ser = Series(np.random.randn(10), idx)
  459. ser2 = Series(np.random.randn(10), idx)
  460. ax = ser.plot(secondary_y=True).right_ax
  461. fig = ax.get_figure()
  462. axes = fig.get_axes()
  463. l = ax.get_lines()[0]
  464. xp = Series(l.get_ydata(), l.get_xdata()).to_timestamp()
  465. assert_series_equal(ser, xp)
  466. self.assertEqual(ax.get_yaxis().get_ticks_position(), 'right')
  467. self.assertFalse(axes[0].get_yaxis().get_visible())
  468. plt.close(fig)
  469. ax2 = ser2.plot()
  470. self.assertEqual(ax2.get_yaxis().get_ticks_position(), 'default')
  471. plt.close(ax2.get_figure())
  472. ax = ser2.plot()
  473. ax2 = ser.plot(secondary_y=True)
  474. self.assertTrue(ax.get_yaxis().get_visible())
  475. @slow
  476. def test_secondary_kde(self):
  477. tm._skip_if_no_scipy()
  478. _skip_if_no_scipy_gaussian_kde()
  479. import matplotlib.pyplot as plt
  480. ser = Series(np.random.randn(10))
  481. ax = ser.plot(secondary_y=True, kind='density').right_ax
  482. fig = ax.get_figure()
  483. axes = fig.get_axes()
  484. self.assertEqual(axes[1].get_yaxis().get_ticks_position(), 'right')
  485. @slow
  486. def test_secondary_bar(self):
  487. ser = Series(np.random.randn(10))
  488. ax = ser.plot(secondary_y=True, kind='bar')
  489. fig = ax.get_figure()
  490. axes = fig.get_axes()
  491. self.assertEqual(axes[1].get_yaxis().get_ticks_position(), 'right')
  492. @slow
  493. def test_secondary_frame(self):
  494. df = DataFrame(np.random.randn(5, 3), columns=['a', 'b', 'c'])
  495. axes = df.plot(secondary_y=['a', 'c'], subplots=True)
  496. self.assertEqual(axes[0].get_yaxis().get_ticks_position(), 'right')
  497. self.assertEqual(axes[1].get_yaxis().get_ticks_position(), 'default')
  498. self.assertEqual(axes[2].get_yaxis().get_ticks_position(), 'right')
  499. @slow
  500. def test_secondary_bar_frame(self):
  501. df = DataFrame(np.random.randn(5, 3), columns=['a', 'b', 'c'])
  502. axes = df.plot(kind='bar', secondary_y=['a', 'c'], subplots=True)
  503. self.assertEqual(axes[0].get_yaxis().get_ticks_position(), 'right')
  504. self.assertEqual(axes[1].get_yaxis().get_ticks_position(), 'default')
  505. self.assertEqual(axes[2].get_yaxis().get_ticks_position(), 'right')
  506. def test_mixed_freq_regular_first(self):
  507. import matplotlib.pyplot as plt
  508. s1 = tm.makeTimeSeries()
  509. s2 = s1[[0, 5, 10, 11, 12, 13, 14, 15]]
  510. ax = s1.plot()
  511. ax2 = s2.plot(style='g')
  512. lines = ax2.get_lines()
  513. idx1 = lines[0].get_xdata()
  514. idx2 = lines[1].get_xdata()
  515. self.assertTrue(idx1.equals(s1.index.to_period('B')))
  516. self.assertTrue(idx2.equals(s2.index.to_period('B')))
  517. left, right = ax2.get_xlim()
  518. pidx = s1.index.to_period()
  519. self.assertEqual(left, pidx[0].ordinal)
  520. self.assertEqual(right, pidx[-1].ordinal)
  521. @slow
  522. def test_mixed_freq_irregular_first(self):
  523. import matplotlib.pyplot as plt
  524. s1 = tm.makeTimeSeries()
  525. s2 = s1[[0, 5, 10, 11, 12, 13, 14, 15]]
  526. s2.plot(style='g')
  527. ax = s1.plot()
  528. self.assertFalse(hasattr(ax, 'freq'))
  529. lines = ax.get_lines()
  530. x1 = lines[0].get_xdata()
  531. assert_array_equal(x1, s2.index.asobject.values)
  532. x2 = lines[1].get_xdata()
  533. assert_array_equal(x2, s1.index.asobject.values)
  534. def test_mixed_freq_hf_first(self):
  535. idxh = date_range('1/1/1999', periods=365, freq='D')
  536. idxl = date_range('1/1/1999', periods=12, freq='M')
  537. high = Series(np.random.randn(len(idxh)), idxh)
  538. low = Series(np.random.randn(len(idxl)), idxl)
  539. high.plot()
  540. ax = low.plot()
  541. for l in ax.get_lines():
  542. self.assertEqual(PeriodIndex(data=l.get_xdata()).freq, 'D')
  543. @slow
  544. def test_mixed_freq_alignment(self):
  545. ts_ind = date_range('2012-01-01 13:00', '2012-01-02', freq='H')
  546. ts_data = np.random.randn(12)
  547. ts = Series(ts_data, index=ts_ind)
  548. ts2 = ts.asfreq('T').interpolate()
  549. ax = ts.plot()
  550. ts2.plot(style='r')
  551. self.assertEqual(ax.lines[0].get_xdata()[0],
  552. ax.lines[1].get_xdata()[0])
  553. @slow
  554. def test_mixed_freq_lf_first(self):
  555. import matplotlib.pyplot as plt
  556. idxh = date_range('1/1/1999', periods=365, freq='D')
  557. idxl = date_range('1/1/1999', periods=12, freq='M')
  558. high = Series(np.random.randn(len(idxh)), idxh)
  559. low = Series(np.random.randn(len(idxl)), idxl)
  560. low.plot(legend=True)
  561. ax = high.plot(legend=True)
  562. for l in ax.get_lines():
  563. self.assertEqual(PeriodIndex(data=l.get_xdata()).freq, 'D')
  564. leg = ax.get_legend()
  565. self.assertEqual(len(leg.texts), 2)
  566. plt.close(ax.get_figure())
  567. idxh = date_range('1/1/1999', periods=240, freq='T')
  568. idxl = date_range('1/1/1999', periods=4, freq='H')
  569. high = Series(np.random.randn(len(idxh)), idxh)
  570. low = Series(np.random.randn(len(idxl)), idxl)
  571. low.plot()
  572. ax = high.plot()
  573. for l in ax.get_lines():
  574. self.assertEqual(PeriodIndex(data=l.get_xdata()).freq, 'T')
  575. def test_mixed_freq_irreg_period(self):
  576. ts = tm.makeTimeSeries()
  577. irreg = ts[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 16, 17, 18, 29]]
  578. rng = period_range('1/3/2000', periods=30, freq='B')
  579. ps = Series(np.random.randn(len(rng)), rng)
  580. irreg.plot()
  581. ps.plot()
  582. @slow
  583. def test_to_weekly_resampling(self):
  584. idxh = date_range('1/1/1999', periods=52, freq='W')
  585. idxl = date_range('1/1/1999', periods=12, freq='M')
  586. high = Series(np.random.randn(len(idxh)), idxh)
  587. low = Series(np.random.randn(len(idxl)), idxl)
  588. high.plot()
  589. ax = low.plot()
  590. for l in ax.get_lines():
  591. self.assertTrue(PeriodIndex(data=l.get_xdata()).freq.startswith('W'))
  592. @slow
  593. def test_from_weekly_resampling(self):
  594. idxh = date_range('1/1/1999', periods=52, freq='W')
  595. idxl = date_range('1/1/1999', periods=12, freq='M')
  596. high = Series(np.random.randn(len(idxh)), idxh)
  597. low = Series(np.random.randn(len(idxl)), idxl)
  598. low.plot()
  599. ax = high.plot()
  600. for l in ax.get_lines():
  601. self.assertTrue(PeriodIndex(data=l.get_xdata()).freq.startswith('W'))
  602. @slow
  603. def test_irreg_dtypes(self):
  604. # date
  605. idx = [date(2000, 1, 1), date(2000, 1, 5), date(2000, 1, 20)]
  606. df = DataFrame(np.random.randn(len(idx), 3), Index(idx, dtype=object))
  607. _check_plot_works(df.plot)
  608. # np.datetime64
  609. idx = date_range('1/1/2000', periods=10)
  610. idx = idx[[0, 2, 5, 9]].asobject
  611. df = DataFrame(np.random.randn(len(idx), 3), idx)
  612. _check_plot_works(df.plot)
  613. @slow
  614. def test_time(self):
  615. t = datetime(1, 1, 1, 3, 30, 0)
  616. deltas = np.random.randint(1, 20, 3).cumsum()
  617. ts = np.array([(t + timedelta(minutes=int(x))).time() for x in deltas])
  618. df = DataFrame({'a': np.random.randn(len(ts)),
  619. 'b': np.random.randn(len(ts))},
  620. index=ts)
  621. ax = df.plot()
  622. # verify tick labels
  623. ticks = ax.get_xticks()
  624. labels = ax.get_xticklabels()
  625. for t, l in zip(ticks, labels):
  626. m, s = divmod(int(t), 60)
  627. h, m = divmod(m, 60)
  628. xp = l.get_text()
  629. if len(xp) > 0:
  630. rs = time(h, m, s).strftime('%H:%M:%S')
  631. self.assertEqual(xp, rs)
  632. # change xlim
  633. ax.set_xlim('1:30', '5:00')
  634. # check tick labels again
  635. ticks = ax.get_xticks()
  636. labels = ax.get_xticklabels()
  637. for t, l in zip(ticks, labels):
  638. m, s = divmod(int(t), 60)
  639. h, m = divmod(m, 60)
  640. xp = l.get_text()
  641. if len(xp) > 0:
  642. rs = time(h, m, s).strftime('%H:%M:%S')
  643. self.assertEqual(xp, rs)
  644. @slow
  645. def test_time_musec(self):
  646. t = datetime(1, 1, 1, 3, 30, 0)
  647. deltas = np.random.randint(1, 20, 3).cumsum()
  648. ts = np.array([(t + timedelta(microseconds=int(x))).time()
  649. for x in deltas])
  650. df = DataFrame({'a': np.random.randn(len(ts)),
  651. 'b': np.random.randn(len(ts))},
  652. index=ts)
  653. ax = df.plot()
  654. # verify tick labels
  655. ticks = ax.get_xticks()
  656. labels = ax.get_xticklabels()
  657. for t, l in zip(ticks, labels):
  658. m, s = divmod(int(t), 60)
  659. us = int((t - int(t)) * 1e6)
  660. h, m = divmod(m, 60)
  661. xp = l.get_text()
  662. if len(xp) > 0:
  663. rs = time(h, m, s).strftime('%H:%M:%S.%f')
  664. self.assertEqual(xp, rs)
  665. @slow
  666. def test_secondary_upsample(self):
  667. idxh = date_range('1/1/1999', periods=365, freq='D')
  668. idxl = date_range('1/1/1999', periods=12, freq='M')
  669. high = Series(np.random.randn(len(idxh)), idxh)
  670. low = Series(np.random.randn(len(idxl)), idxl)
  671. low.plot()
  672. ax = high.plot(secondary_y=True)
  673. for l in ax.get_lines():
  674. self.assertEqual(l.get_xdata().freq, 'D')
  675. for l in ax.right_ax.get_lines():
  676. self.assertEqual(l.get_xdata().freq, 'D')
  677. @slow
  678. def test_secondary_legend(self):
  679. import matplotlib.pyplot as plt
  680. fig = plt.gcf()
  681. plt.clf()
  682. ax = fig.add_subplot(211)
  683. # ts
  684. df = tm.makeTimeDataFrame()
  685. ax = df.plot(secondary_y=['A', 'B'])
  686. leg = ax.get_legend()
  687. self.assertEqual(len(leg.get_lines()), 4)
  688. self.assertEqual(leg.get_texts()[0].get_text(), 'A (right)')
  689. self.assertEqual(leg.get_texts()[1].get_text(), 'B (right)')
  690. self.assertEqual(leg.get_texts()[2].get_text(), 'C')
  691. self.assertEqual(leg.get_texts()[3].get_text(), 'D')
  692. self.assertIsNone(ax.right_ax.get_legend())
  693. colors = set()
  694. for line in leg.get_lines():
  695. colors.add(line.get_color())
  696. # TODO: color cycle problems
  697. self.assertEqual(len(colors), 4)
  698. plt.clf()
  699. ax = fig.add_subplot(211)
  700. ax = df.plot(secondary_y=['A', 'C'], mark_right=False)
  701. leg = ax.get_legend()
  702. self.assertEqual(len(leg.get_lines()), 4)
  703. self.assertEqual(leg.get_texts()[0].get_text(), 'A')
  704. self.assertEqual(leg.get_texts()[1].get_text(), 'B')
  705. self.assertEqual(leg.get_texts()[2].get_text(), 'C')
  706. self.assertEqual(leg.get_texts()[3].get_text(), 'D')
  707. plt.clf()
  708. ax = df.plot(kind='bar', secondary_y=['A'])
  709. leg = ax.get_legend()
  710. self.assertEqual(leg.get_texts()[0].get_text(), 'A (right)')
  711. self.assertEqual(leg.get_texts()[1].get_text(), 'B')
  712. plt.clf()
  713. ax = df.plot(kind='bar', secondary_y=['A'], mark_right=False)
  714. leg = ax.get_legend()
  715. self.assertEqual(leg.get_texts()[0].get_text(), 'A')
  716. self.assertEqual(leg.get_texts()[1].get_text(), 'B')
  717. plt.clf()
  718. ax = fig.add_subplot(211)
  719. df = tm.makeTimeDataFrame()
  720. ax = df.plot(secondary_y=['C', 'D'])
  721. leg = ax.get_legend()
  722. self.assertEqual(len(leg.get_lines()), 4)
  723. self.assertIsNone(ax.right_ax.get_legend())
  724. colors = set()
  725. for line in leg.get_lines():
  726. colors.add(line.get_color())
  727. # TODO: color cycle problems
  728. self.assertEqual(len(colors), 4)
  729. # non-ts
  730. df = tm.makeDataFrame()
  731. plt.clf()
  732. ax = fig.add_subplot(211)
  733. ax = df.plot(secondary_y=['A', 'B'])
  734. leg = ax.get_legend()
  735. self.assertEqual(len(leg.get_lines()), 4)
  736. self.assertIsNone(ax.right_ax.get_legend())
  737. colors = set()
  738. for line in leg.get_lines():
  739. colors.add(line.get_color())
  740. # TODO: color cycle problems
  741. self.assertEqual(len(colors), 4)
  742. plt.clf()
  743. ax = fig.add_subplot(211)
  744. ax = df.plot(secondary_y=['C', 'D'])
  745. leg = ax.get_legend()
  746. self.assertEqual(len(leg.get_lines()), 4)
  747. self.assertIsNone(ax.right_ax.get_legend())
  748. colors = set()
  749. for line in leg.get_lines():
  750. colors.add(line.get_color())
  751. # TODO: color cycle problems
  752. self.assertEqual(len(colors), 4)
  753. def test_format_date_axis(self):
  754. rng = date_range('1/1/2012', periods=12, freq='M')
  755. df = DataFrame(np.random.randn(len(rng), 3), rng)
  756. ax = df.plot()
  757. xaxis = ax.get_xaxis()
  758. for l in xaxis.get_ticklabels():
  759. if len(l.get_text()) > 0:
  760. self.assertEqual(l.get_rotation(), 30)
  761. @slow
  762. def test_ax_plot(self):
  763. import matplotlib.pyplot as plt
  764. x = DatetimeIndex(start='2012-01-02', periods=10,
  765. freq='D')
  766. y = lrange(len(x))
  767. fig = plt.figure()
  768. ax = fig.add_subplot(111)
  769. lines = ax.plot(x, y, label='Y')
  770. assert_array_equal(DatetimeIndex(lines[0].get_xdata()), x)
  771. @slow
  772. def test_mpl_nopandas(self):
  773. import matplotlib.pyplot as plt
  774. dates = [date(2008, 12, 31), date(2009, 1, 31)]
  775. values1 = np.arange(10.0, 11.0, 0.5)
  776. values2 = np.arange(11.0, 12.0, 0.5)
  777. kw = dict(fmt='-', lw=4)
  778. plt.close('all')
  779. fig = plt.figure()
  780. ax = fig.add_subplot(111)
  781. ax.plot_date([x.toordinal() for x in dates], values1, **kw)
  782. ax.plot_date([x.toordinal() for x in dates], values2, **kw)
  783. line1, line2 = ax.get_lines()
  784. assert_array_equal(np.array([x.toordinal() for x in dates]),
  785. line1.get_xydata()[:, 0])
  786. assert_array_equal(np.array([x.toordinal() for x in dates]),
  787. line2.get_xydata()[:, 0])
  788. @slow
  789. def test_irregular_ts_shared_ax_xlim(self):
  790. # GH 2960
  791. ts = tm.makeTimeSeries()[:20]
  792. ts_irregular = ts[[1, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, 17, 18]]
  793. # plot the left section of the irregular series, then the right section
  794. ax = ts_irregular[:5].plot()
  795. ts_irregular[5:].plot(ax=ax)
  796. # check that axis limits are correct
  797. left, right = ax.get_xlim()
  798. self.assertEqual(left, ts_irregular.index.min().toordinal())
  799. self.assertEqual(right, ts_irregular.index.max().toordinal())
  800. @slow
  801. def test_secondary_y_non_ts_xlim(self):
  802. # GH 3490 - non-timeseries with secondary y
  803. index_1 = [1, 2, 3, 4]
  804. index_2 = [5, 6, 7, 8]
  805. s1 = Series(1, index=index_1)
  806. s2 = Series(2, index=index_2)
  807. ax = s1.plot()
  808. left_before, right_before = ax.get_xlim()
  809. s2.plot(secondary_y=True, ax=ax)
  810. left_after, right_after = ax.get_xlim()
  811. self.assertEqual(left_before, left_after)
  812. self.assertTrue(right_before < right_after)
  813. @slow
  814. def test_secondary_y_regular_ts_xlim(self):
  815. # GH 3490 - regular-timeseries with secondary y
  816. index_1 = date_range(start='2000-01-01', periods=4, freq='D')
  817. index_2 = date_range(start='2000-01-05', periods=4, freq='D')
  818. s1 = Series(1, index=index_1)
  819. s2 = Series(2, index=index_2)
  820. ax = s1.plot()
  821. left_before, right_before = ax.get_xlim()
  822. s2.plot(secondary_y=True, ax=ax)
  823. left_after, right_after = ax.get_xlim()
  824. self.assertEqual(left_before, left_after)
  825. self.assertTrue(right_before < right_after)
  826. @slow
  827. def test_secondary_y_mixed_freq_ts_xlim(self):
  828. # GH 3490 - mixed frequency timeseries with secondary y
  829. rng = date_range('2000-01-01', periods=10000, freq='min')
  830. ts = Series(1, index=rng)
  831. ax = ts.plot()
  832. left_before, right_before = ax.get_xlim()
  833. ts.resample('D').plot(secondary_y=True, ax=ax)
  834. left_after, right_after = ax.get_xlim()
  835. # a downsample should not have changed either limit
  836. self.assertEqual(left_before, left_after)
  837. self.assertEqual(right_before, right_after)
  838. @slow
  839. def test_secondary_y_irregular_ts_xlim(self):
  840. # GH 3490 - irregular-timeseries with secondary y
  841. ts = tm.makeTimeSeries()[:20]
  842. ts_irregular = ts[[1, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, 17, 18]]
  843. ax = ts_irregular[:5].plot()
  844. # plot higher-x values on secondary axis
  845. ts_irregular[5:].plot(secondary_y=True, ax=ax)
  846. # ensure secondary limits aren't overwritten by plot on primary
  847. ts_irregular[:5].plot(ax=ax)
  848. left, right = ax.get_xlim()
  849. self.assertEqual(left, ts_irregular.index.min().toordinal())
  850. self.assertEqual(right, ts_irregular.index.max().toordinal())
  851. def _check_plot_works(f, freq=None, series=None, *args, **kwargs):
  852. import matplotlib.pyplot as plt
  853. fig = plt.gcf()
  854. try:
  855. plt.clf()
  856. ax = fig.add_subplot(211)
  857. orig_ax = kwargs.pop('ax', plt.gca())
  858. orig_axfreq = getattr(orig_ax, 'freq', None)
  859. ret = f(*args, **kwargs)
  860. assert ret is not None # do something more intelligent
  861. ax = kwargs.pop('ax', plt.gca())
  862. if series is not None:
  863. dfreq = series.index.freq
  864. if isinstance(dfreq, DateOffset):
  865. dfreq = dfreq.rule_code
  866. if orig_axfreq is None:
  867. assert ax.freq == dfreq
  868. if freq is not None and orig_axfreq is None:
  869. assert ax.freq == freq
  870. ax = fig.add_subplot(212)
  871. try:
  872. kwargs['ax'] = ax
  873. ret = f(*args, **kwargs)
  874. assert ret is not None # do something more intelligent
  875. except Exception:
  876. pass
  877. with ensure_clean(return_filelike=True) as path:
  878. plt.savefig(path)
  879. finally:
  880. plt.close(fig)
  881. if __name__ == '__main__':
  882. nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],
  883. exit=False)