test_frame.py 120 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003
  1. # coding: utf-8
  2. """ Test cases for DataFrame.plot """
  3. from datetime import date, datetime
  4. import string
  5. import warnings
  6. import numpy as np
  7. from numpy.random import rand, randn
  8. import pytest
  9. from pandas.compat import PY3, lmap, lrange, lzip, range, u, zip
  10. import pandas.util._test_decorators as td
  11. from pandas.core.dtypes.api import is_list_like
  12. import pandas as pd
  13. from pandas import (
  14. DataFrame, MultiIndex, PeriodIndex, Series, bdate_range, date_range)
  15. from pandas.tests.plotting.common import (
  16. TestPlotBase, _check_plot_works, _ok_for_gaussian_kde,
  17. _skip_if_no_scipy_gaussian_kde)
  18. import pandas.util.testing as tm
  19. from pandas.io.formats.printing import pprint_thing
  20. import pandas.plotting as plotting
  21. @td.skip_if_no_mpl
  22. class TestDataFramePlots(TestPlotBase):
  23. def setup_method(self, method):
  24. TestPlotBase.setup_method(self, method)
  25. import matplotlib as mpl
  26. mpl.rcdefaults()
  27. self.tdf = tm.makeTimeDataFrame()
  28. self.hexbin_df = DataFrame({"A": np.random.uniform(size=20),
  29. "B": np.random.uniform(size=20),
  30. "C": np.arange(20) + np.random.uniform(
  31. size=20)})
  32. def _assert_ytickslabels_visibility(self, axes, expected):
  33. for ax, exp in zip(axes, expected):
  34. self._check_visible(ax.get_yticklabels(), visible=exp)
  35. def _assert_xtickslabels_visibility(self, axes, expected):
  36. for ax, exp in zip(axes, expected):
  37. self._check_visible(ax.get_xticklabels(), visible=exp)
  38. @pytest.mark.slow
  39. def test_plot(self):
  40. df = self.tdf
  41. _check_plot_works(df.plot, grid=False)
  42. # _check_plot_works adds an ax so catch warning. see GH #13188
  43. with tm.assert_produces_warning(UserWarning):
  44. axes = _check_plot_works(df.plot,
  45. subplots=True)
  46. self._check_axes_shape(axes, axes_num=4, layout=(4, 1))
  47. with tm.assert_produces_warning(UserWarning):
  48. axes = _check_plot_works(df.plot,
  49. subplots=True, layout=(-1, 2))
  50. self._check_axes_shape(axes, axes_num=4, layout=(2, 2))
  51. with tm.assert_produces_warning(UserWarning):
  52. axes = _check_plot_works(df.plot,
  53. subplots=True, use_index=False)
  54. self._check_axes_shape(axes, axes_num=4, layout=(4, 1))
  55. df = DataFrame({'x': [1, 2], 'y': [3, 4]})
  56. with pytest.raises(AttributeError, match='Unknown property blarg'):
  57. df.plot.line(blarg=True)
  58. df = DataFrame(np.random.rand(10, 3),
  59. index=list(string.ascii_letters[:10]))
  60. _check_plot_works(df.plot, use_index=True)
  61. _check_plot_works(df.plot, sort_columns=False)
  62. _check_plot_works(df.plot, yticks=[1, 5, 10])
  63. _check_plot_works(df.plot, xticks=[1, 5, 10])
  64. _check_plot_works(df.plot, ylim=(-100, 100), xlim=(-100, 100))
  65. with tm.assert_produces_warning(UserWarning):
  66. _check_plot_works(df.plot, subplots=True, title='blah')
  67. # We have to redo it here because _check_plot_works does two plots,
  68. # once without an ax kwarg and once with an ax kwarg and the new sharex
  69. # behaviour does not remove the visibility of the latter axis (as ax is
  70. # present). see: https://github.com/pandas-dev/pandas/issues/9737
  71. axes = df.plot(subplots=True, title='blah')
  72. self._check_axes_shape(axes, axes_num=3, layout=(3, 1))
  73. # axes[0].figure.savefig("test.png")
  74. for ax in axes[:2]:
  75. self._check_visible(ax.xaxis) # xaxis must be visible for grid
  76. self._check_visible(ax.get_xticklabels(), visible=False)
  77. self._check_visible(ax.get_xticklabels(minor=True), visible=False)
  78. self._check_visible([ax.xaxis.get_label()], visible=False)
  79. for ax in [axes[2]]:
  80. self._check_visible(ax.xaxis)
  81. self._check_visible(ax.get_xticklabels())
  82. self._check_visible([ax.xaxis.get_label()])
  83. self._check_ticks_props(ax, xrot=0)
  84. _check_plot_works(df.plot, title='blah')
  85. tuples = lzip(string.ascii_letters[:10], range(10))
  86. df = DataFrame(np.random.rand(10, 3),
  87. index=MultiIndex.from_tuples(tuples))
  88. _check_plot_works(df.plot, use_index=True)
  89. # unicode
  90. index = MultiIndex.from_tuples([(u('\u03b1'), 0),
  91. (u('\u03b1'), 1),
  92. (u('\u03b2'), 2),
  93. (u('\u03b2'), 3),
  94. (u('\u03b3'), 4),
  95. (u('\u03b3'), 5),
  96. (u('\u03b4'), 6),
  97. (u('\u03b4'), 7)], names=['i0', 'i1'])
  98. columns = MultiIndex.from_tuples([('bar', u('\u0394')),
  99. ('bar', u('\u0395'))], names=['c0',
  100. 'c1'])
  101. df = DataFrame(np.random.randint(0, 10, (8, 2)),
  102. columns=columns,
  103. index=index)
  104. _check_plot_works(df.plot, title=u('\u03A3'))
  105. # GH 6951
  106. # Test with single column
  107. df = DataFrame({'x': np.random.rand(10)})
  108. axes = _check_plot_works(df.plot.bar, subplots=True)
  109. self._check_axes_shape(axes, axes_num=1, layout=(1, 1))
  110. axes = _check_plot_works(df.plot.bar, subplots=True, layout=(-1, 1))
  111. self._check_axes_shape(axes, axes_num=1, layout=(1, 1))
  112. # When ax is supplied and required number of axes is 1,
  113. # passed ax should be used:
  114. fig, ax = self.plt.subplots()
  115. axes = df.plot.bar(subplots=True, ax=ax)
  116. assert len(axes) == 1
  117. result = ax.axes
  118. assert result is axes[0]
  119. # GH 15516
  120. def test_mpl2_color_cycle_str(self):
  121. colors = ['C' + str(x) for x in range(10)]
  122. df = DataFrame(randn(10, 3), columns=['a', 'b', 'c'])
  123. for c in colors:
  124. _check_plot_works(df.plot, color=c)
  125. def test_color_single_series_list(self):
  126. # GH 3486
  127. df = DataFrame({"A": [1, 2, 3]})
  128. _check_plot_works(df.plot, color=['red'])
  129. def test_rgb_tuple_color(self):
  130. # GH 16695
  131. df = DataFrame({'x': [1, 2], 'y': [3, 4]})
  132. _check_plot_works(df.plot, x='x', y='y', color=(1, 0, 0))
  133. _check_plot_works(df.plot, x='x', y='y', color=(1, 0, 0, 0.5))
  134. def test_color_empty_string(self):
  135. df = DataFrame(randn(10, 2))
  136. with pytest.raises(ValueError):
  137. df.plot(color='')
  138. def test_color_and_style_arguments(self):
  139. df = DataFrame({'x': [1, 2], 'y': [3, 4]})
  140. # passing both 'color' and 'style' arguments should be allowed
  141. # if there is no color symbol in the style strings:
  142. ax = df.plot(color=['red', 'black'], style=['-', '--'])
  143. # check that the linestyles are correctly set:
  144. linestyle = [line.get_linestyle() for line in ax.lines]
  145. assert linestyle == ['-', '--']
  146. # check that the colors are correctly set:
  147. color = [line.get_color() for line in ax.lines]
  148. assert color == ['red', 'black']
  149. # passing both 'color' and 'style' arguments should not be allowed
  150. # if there is a color symbol in the style strings:
  151. with pytest.raises(ValueError):
  152. df.plot(color=['red', 'black'], style=['k-', 'r--'])
  153. def test_nonnumeric_exclude(self):
  154. df = DataFrame({'A': ["x", "y", "z"], 'B': [1, 2, 3]})
  155. ax = df.plot()
  156. assert len(ax.get_lines()) == 1 # B was plotted
  157. @pytest.mark.slow
  158. def test_implicit_label(self):
  159. df = DataFrame(randn(10, 3), columns=['a', 'b', 'c'])
  160. ax = df.plot(x='a', y='b')
  161. self._check_text_labels(ax.xaxis.get_label(), 'a')
  162. @pytest.mark.slow
  163. def test_donot_overwrite_index_name(self):
  164. # GH 8494
  165. df = DataFrame(randn(2, 2), columns=['a', 'b'])
  166. df.index.name = 'NAME'
  167. df.plot(y='b', label='LABEL')
  168. assert df.index.name == 'NAME'
  169. @pytest.mark.slow
  170. def test_plot_xy(self):
  171. # columns.inferred_type == 'string'
  172. df = self.tdf
  173. self._check_data(df.plot(x=0, y=1), df.set_index('A')['B'].plot())
  174. self._check_data(df.plot(x=0), df.set_index('A').plot())
  175. self._check_data(df.plot(y=0), df.B.plot())
  176. self._check_data(df.plot(x='A', y='B'), df.set_index('A').B.plot())
  177. self._check_data(df.plot(x='A'), df.set_index('A').plot())
  178. self._check_data(df.plot(y='B'), df.B.plot())
  179. # columns.inferred_type == 'integer'
  180. df.columns = lrange(1, len(df.columns) + 1)
  181. self._check_data(df.plot(x=1, y=2), df.set_index(1)[2].plot())
  182. self._check_data(df.plot(x=1), df.set_index(1).plot())
  183. self._check_data(df.plot(y=1), df[1].plot())
  184. # figsize and title
  185. ax = df.plot(x=1, y=2, title='Test', figsize=(16, 8))
  186. self._check_text_labels(ax.title, 'Test')
  187. self._check_axes_shape(ax, axes_num=1, layout=(1, 1),
  188. figsize=(16., 8.))
  189. # columns.inferred_type == 'mixed'
  190. # TODO add MultiIndex test
  191. @pytest.mark.slow
  192. def test_logscales(self):
  193. df = DataFrame({'a': np.arange(100)}, index=np.arange(100))
  194. ax = df.plot(logy=True)
  195. self._check_ax_scales(ax, yaxis='log')
  196. ax = df.plot(logx=True)
  197. self._check_ax_scales(ax, xaxis='log')
  198. ax = df.plot(loglog=True)
  199. self._check_ax_scales(ax, xaxis='log', yaxis='log')
  200. @pytest.mark.slow
  201. def test_xcompat(self):
  202. import pandas as pd
  203. df = self.tdf
  204. ax = df.plot(x_compat=True)
  205. lines = ax.get_lines()
  206. assert not isinstance(lines[0].get_xdata(), PeriodIndex)
  207. tm.close()
  208. pd.plotting.plot_params['xaxis.compat'] = True
  209. ax = df.plot()
  210. lines = ax.get_lines()
  211. assert not isinstance(lines[0].get_xdata(), PeriodIndex)
  212. tm.close()
  213. pd.plotting.plot_params['x_compat'] = False
  214. ax = df.plot()
  215. lines = ax.get_lines()
  216. assert not isinstance(lines[0].get_xdata(), PeriodIndex)
  217. assert isinstance(PeriodIndex(lines[0].get_xdata()), PeriodIndex)
  218. tm.close()
  219. # useful if you're plotting a bunch together
  220. with pd.plotting.plot_params.use('x_compat', True):
  221. ax = df.plot()
  222. lines = ax.get_lines()
  223. assert not isinstance(lines[0].get_xdata(), PeriodIndex)
  224. tm.close()
  225. ax = df.plot()
  226. lines = ax.get_lines()
  227. assert not isinstance(lines[0].get_xdata(), PeriodIndex)
  228. assert isinstance(PeriodIndex(lines[0].get_xdata()), PeriodIndex)
  229. def test_period_compat(self):
  230. # GH 9012
  231. # period-array conversions
  232. df = DataFrame(
  233. np.random.rand(21, 2),
  234. index=bdate_range(datetime(2000, 1, 1), datetime(2000, 1, 31)),
  235. columns=['a', 'b'])
  236. df.plot()
  237. self.plt.axhline(y=0)
  238. tm.close()
  239. def test_unsorted_index(self):
  240. df = DataFrame({'y': np.arange(100)}, index=np.arange(99, -1, -1),
  241. dtype=np.int64)
  242. ax = df.plot()
  243. lines = ax.get_lines()[0]
  244. rs = lines.get_xydata()
  245. rs = Series(rs[:, 1], rs[:, 0], dtype=np.int64, name='y')
  246. tm.assert_series_equal(rs, df.y, check_index_type=False)
  247. tm.close()
  248. df.index = pd.Index(np.arange(99, -1, -1), dtype=np.float64)
  249. ax = df.plot()
  250. lines = ax.get_lines()[0]
  251. rs = lines.get_xydata()
  252. rs = Series(rs[:, 1], rs[:, 0], dtype=np.int64, name='y')
  253. tm.assert_series_equal(rs, df.y)
  254. def test_unsorted_index_lims(self):
  255. df = DataFrame({'y': [0., 1., 2., 3.]}, index=[1., 0., 3., 2.])
  256. ax = df.plot()
  257. xmin, xmax = ax.get_xlim()
  258. lines = ax.get_lines()
  259. assert xmin <= np.nanmin(lines[0].get_data()[0])
  260. assert xmax >= np.nanmax(lines[0].get_data()[0])
  261. df = DataFrame({'y': [0., 1., np.nan, 3., 4., 5., 6.]},
  262. index=[1., 0., 3., 2., np.nan, 3., 2.])
  263. ax = df.plot()
  264. xmin, xmax = ax.get_xlim()
  265. lines = ax.get_lines()
  266. assert xmin <= np.nanmin(lines[0].get_data()[0])
  267. assert xmax >= np.nanmax(lines[0].get_data()[0])
  268. df = DataFrame({'y': [0., 1., 2., 3.], 'z': [91., 90., 93., 92.]})
  269. ax = df.plot(x='z', y='y')
  270. xmin, xmax = ax.get_xlim()
  271. lines = ax.get_lines()
  272. assert xmin <= np.nanmin(lines[0].get_data()[0])
  273. assert xmax >= np.nanmax(lines[0].get_data()[0])
  274. @pytest.mark.slow
  275. def test_subplots(self):
  276. df = DataFrame(np.random.rand(10, 3),
  277. index=list(string.ascii_letters[:10]))
  278. for kind in ['bar', 'barh', 'line', 'area']:
  279. axes = df.plot(kind=kind, subplots=True, sharex=True, legend=True)
  280. self._check_axes_shape(axes, axes_num=3, layout=(3, 1))
  281. assert axes.shape == (3, )
  282. for ax, column in zip(axes, df.columns):
  283. self._check_legend_labels(ax,
  284. labels=[pprint_thing(column)])
  285. for ax in axes[:-2]:
  286. self._check_visible(ax.xaxis) # xaxis must be visible for grid
  287. self._check_visible(ax.get_xticklabels(), visible=False)
  288. self._check_visible(
  289. ax.get_xticklabels(minor=True), visible=False)
  290. self._check_visible(ax.xaxis.get_label(), visible=False)
  291. self._check_visible(ax.get_yticklabels())
  292. self._check_visible(axes[-1].xaxis)
  293. self._check_visible(axes[-1].get_xticklabels())
  294. self._check_visible(axes[-1].get_xticklabels(minor=True))
  295. self._check_visible(axes[-1].xaxis.get_label())
  296. self._check_visible(axes[-1].get_yticklabels())
  297. axes = df.plot(kind=kind, subplots=True, sharex=False)
  298. for ax in axes:
  299. self._check_visible(ax.xaxis)
  300. self._check_visible(ax.get_xticklabels())
  301. self._check_visible(ax.get_xticklabels(minor=True))
  302. self._check_visible(ax.xaxis.get_label())
  303. self._check_visible(ax.get_yticklabels())
  304. axes = df.plot(kind=kind, subplots=True, legend=False)
  305. for ax in axes:
  306. assert ax.get_legend() is None
  307. def test_groupby_boxplot_sharey(self):
  308. # https://github.com/pandas-dev/pandas/issues/20968
  309. # sharey can now be switched check whether the right
  310. # pair of axes is turned on or off
  311. df = DataFrame({'a': [-1.43, -0.15, -3.70, -1.43, -0.14],
  312. 'b': [0.56, 0.84, 0.29, 0.56, 0.85],
  313. 'c': [0, 1, 2, 3, 1]},
  314. index=[0, 1, 2, 3, 4])
  315. # behavior without keyword
  316. axes = df.groupby('c').boxplot()
  317. expected = [True, False, True, False]
  318. self._assert_ytickslabels_visibility(axes, expected)
  319. # set sharey=True should be identical
  320. axes = df.groupby('c').boxplot(sharey=True)
  321. expected = [True, False, True, False]
  322. self._assert_ytickslabels_visibility(axes, expected)
  323. # sharey=False, all yticklabels should be visible
  324. axes = df.groupby('c').boxplot(sharey=False)
  325. expected = [True, True, True, True]
  326. self._assert_ytickslabels_visibility(axes, expected)
  327. def test_groupby_boxplot_sharex(self):
  328. # https://github.com/pandas-dev/pandas/issues/20968
  329. # sharex can now be switched check whether the right
  330. # pair of axes is turned on or off
  331. df = DataFrame({'a': [-1.43, -0.15, -3.70, -1.43, -0.14],
  332. 'b': [0.56, 0.84, 0.29, 0.56, 0.85],
  333. 'c': [0, 1, 2, 3, 1]},
  334. index=[0, 1, 2, 3, 4])
  335. # behavior without keyword
  336. axes = df.groupby('c').boxplot()
  337. expected = [True, True, True, True]
  338. self._assert_xtickslabels_visibility(axes, expected)
  339. # set sharex=False should be identical
  340. axes = df.groupby('c').boxplot(sharex=False)
  341. expected = [True, True, True, True]
  342. self._assert_xtickslabels_visibility(axes, expected)
  343. # sharex=True, yticklabels should be visible
  344. # only for bottom plots
  345. axes = df.groupby('c').boxplot(sharex=True)
  346. expected = [False, False, True, True]
  347. self._assert_xtickslabels_visibility(axes, expected)
  348. @pytest.mark.slow
  349. def test_subplots_timeseries(self):
  350. idx = date_range(start='2014-07-01', freq='M', periods=10)
  351. df = DataFrame(np.random.rand(10, 3), index=idx)
  352. for kind in ['line', 'area']:
  353. axes = df.plot(kind=kind, subplots=True, sharex=True)
  354. self._check_axes_shape(axes, axes_num=3, layout=(3, 1))
  355. for ax in axes[:-2]:
  356. # GH 7801
  357. self._check_visible(ax.xaxis) # xaxis must be visible for grid
  358. self._check_visible(ax.get_xticklabels(), visible=False)
  359. self._check_visible(
  360. ax.get_xticklabels(minor=True), visible=False)
  361. self._check_visible(ax.xaxis.get_label(), visible=False)
  362. self._check_visible(ax.get_yticklabels())
  363. self._check_visible(axes[-1].xaxis)
  364. self._check_visible(axes[-1].get_xticklabels())
  365. self._check_visible(axes[-1].get_xticklabels(minor=True))
  366. self._check_visible(axes[-1].xaxis.get_label())
  367. self._check_visible(axes[-1].get_yticklabels())
  368. self._check_ticks_props(axes, xrot=0)
  369. axes = df.plot(kind=kind, subplots=True, sharex=False, rot=45,
  370. fontsize=7)
  371. for ax in axes:
  372. self._check_visible(ax.xaxis)
  373. self._check_visible(ax.get_xticklabels())
  374. self._check_visible(ax.get_xticklabels(minor=True))
  375. self._check_visible(ax.xaxis.get_label())
  376. self._check_visible(ax.get_yticklabels())
  377. self._check_ticks_props(ax, xlabelsize=7, xrot=45,
  378. ylabelsize=7)
  379. def test_subplots_timeseries_y_axis(self):
  380. # GH16953
  381. data = {"numeric": np.array([1, 2, 5]),
  382. "timedelta": [pd.Timedelta(-10, unit="s"),
  383. pd.Timedelta(10, unit="m"),
  384. pd.Timedelta(10, unit="h")],
  385. "datetime_no_tz": [pd.to_datetime("2017-08-01 00:00:00"),
  386. pd.to_datetime("2017-08-01 02:00:00"),
  387. pd.to_datetime("2017-08-02 00:00:00")],
  388. "datetime_all_tz": [pd.to_datetime("2017-08-01 00:00:00",
  389. utc=True),
  390. pd.to_datetime("2017-08-01 02:00:00",
  391. utc=True),
  392. pd.to_datetime("2017-08-02 00:00:00",
  393. utc=True)],
  394. "text": ["This", "should", "fail"]}
  395. testdata = DataFrame(data)
  396. ax_numeric = testdata.plot(y="numeric")
  397. assert (ax_numeric.get_lines()[0].get_data()[1] ==
  398. testdata["numeric"].values).all()
  399. ax_timedelta = testdata.plot(y="timedelta")
  400. assert (ax_timedelta.get_lines()[0].get_data()[1] ==
  401. testdata["timedelta"].values).all()
  402. ax_datetime_no_tz = testdata.plot(y="datetime_no_tz")
  403. assert (ax_datetime_no_tz.get_lines()[0].get_data()[1] ==
  404. testdata["datetime_no_tz"].values).all()
  405. ax_datetime_all_tz = testdata.plot(y="datetime_all_tz")
  406. assert (ax_datetime_all_tz.get_lines()[0].get_data()[1] ==
  407. testdata["datetime_all_tz"].values).all()
  408. with pytest.raises(TypeError):
  409. testdata.plot(y="text")
  410. @pytest.mark.xfail(reason='not support for period, categorical, '
  411. 'datetime_mixed_tz')
  412. def test_subplots_timeseries_y_axis_not_supported(self):
  413. """
  414. This test will fail for:
  415. period:
  416. since period isn't yet implemented in ``select_dtypes``
  417. and because it will need a custom value converter +
  418. tick formater (as was done for x-axis plots)
  419. categorical:
  420. because it will need a custom value converter +
  421. tick formater (also doesn't work for x-axis, as of now)
  422. datetime_mixed_tz:
  423. because of the way how pandas handels ``Series`` of
  424. ``datetime`` objects with different timezone,
  425. generally converting ``datetime`` objects in a tz-aware
  426. form could help with this problem
  427. """
  428. data = {"numeric": np.array([1, 2, 5]),
  429. "period": [pd.Period('2017-08-01 00:00:00', freq='H'),
  430. pd.Period('2017-08-01 02:00', freq='H'),
  431. pd.Period('2017-08-02 00:00:00', freq='H')],
  432. "categorical": pd.Categorical(["c", "b", "a"],
  433. categories=["a", "b", "c"],
  434. ordered=False),
  435. "datetime_mixed_tz": [pd.to_datetime("2017-08-01 00:00:00",
  436. utc=True),
  437. pd.to_datetime("2017-08-01 02:00:00"),
  438. pd.to_datetime("2017-08-02 00:00:00")]}
  439. testdata = pd.DataFrame(data)
  440. ax_period = testdata.plot(x="numeric", y="period")
  441. assert (ax_period.get_lines()[0].get_data()[1] ==
  442. testdata["period"].values).all()
  443. ax_categorical = testdata.plot(x="numeric", y="categorical")
  444. assert (ax_categorical.get_lines()[0].get_data()[1] ==
  445. testdata["categorical"].values).all()
  446. ax_datetime_mixed_tz = testdata.plot(x="numeric",
  447. y="datetime_mixed_tz")
  448. assert (ax_datetime_mixed_tz.get_lines()[0].get_data()[1] ==
  449. testdata["datetime_mixed_tz"].values).all()
  450. @pytest.mark.slow
  451. def test_subplots_layout(self):
  452. # GH 6667
  453. df = DataFrame(np.random.rand(10, 3),
  454. index=list(string.ascii_letters[:10]))
  455. axes = df.plot(subplots=True, layout=(2, 2))
  456. self._check_axes_shape(axes, axes_num=3, layout=(2, 2))
  457. assert axes.shape == (2, 2)
  458. axes = df.plot(subplots=True, layout=(-1, 2))
  459. self._check_axes_shape(axes, axes_num=3, layout=(2, 2))
  460. assert axes.shape == (2, 2)
  461. axes = df.plot(subplots=True, layout=(2, -1))
  462. self._check_axes_shape(axes, axes_num=3, layout=(2, 2))
  463. assert axes.shape == (2, 2)
  464. axes = df.plot(subplots=True, layout=(1, 4))
  465. self._check_axes_shape(axes, axes_num=3, layout=(1, 4))
  466. assert axes.shape == (1, 4)
  467. axes = df.plot(subplots=True, layout=(-1, 4))
  468. self._check_axes_shape(axes, axes_num=3, layout=(1, 4))
  469. assert axes.shape == (1, 4)
  470. axes = df.plot(subplots=True, layout=(4, -1))
  471. self._check_axes_shape(axes, axes_num=3, layout=(4, 1))
  472. assert axes.shape == (4, 1)
  473. with pytest.raises(ValueError):
  474. df.plot(subplots=True, layout=(1, 1))
  475. with pytest.raises(ValueError):
  476. df.plot(subplots=True, layout=(-1, -1))
  477. # single column
  478. df = DataFrame(np.random.rand(10, 1),
  479. index=list(string.ascii_letters[:10]))
  480. axes = df.plot(subplots=True)
  481. self._check_axes_shape(axes, axes_num=1, layout=(1, 1))
  482. assert axes.shape == (1, )
  483. axes = df.plot(subplots=True, layout=(3, 3))
  484. self._check_axes_shape(axes, axes_num=1, layout=(3, 3))
  485. assert axes.shape == (3, 3)
  486. @pytest.mark.slow
  487. def test_subplots_warnings(self):
  488. # GH 9464
  489. with tm.assert_produces_warning(None):
  490. df = DataFrame(np.random.randn(100, 4))
  491. df.plot(subplots=True, layout=(3, 2))
  492. df = DataFrame(np.random.randn(100, 4),
  493. index=date_range('1/1/2000', periods=100))
  494. df.plot(subplots=True, layout=(3, 2))
  495. @pytest.mark.slow
  496. def test_subplots_multiple_axes(self):
  497. # GH 5353, 6970, GH 7069
  498. fig, axes = self.plt.subplots(2, 3)
  499. df = DataFrame(np.random.rand(10, 3),
  500. index=list(string.ascii_letters[:10]))
  501. returned = df.plot(subplots=True, ax=axes[0], sharex=False,
  502. sharey=False)
  503. self._check_axes_shape(returned, axes_num=3, layout=(1, 3))
  504. assert returned.shape == (3, )
  505. assert returned[0].figure is fig
  506. # draw on second row
  507. returned = df.plot(subplots=True, ax=axes[1], sharex=False,
  508. sharey=False)
  509. self._check_axes_shape(returned, axes_num=3, layout=(1, 3))
  510. assert returned.shape == (3, )
  511. assert returned[0].figure is fig
  512. self._check_axes_shape(axes, axes_num=6, layout=(2, 3))
  513. tm.close()
  514. with pytest.raises(ValueError):
  515. fig, axes = self.plt.subplots(2, 3)
  516. # pass different number of axes from required
  517. df.plot(subplots=True, ax=axes)
  518. # pass 2-dim axes and invalid layout
  519. # invalid lauout should not affect to input and return value
  520. # (show warning is tested in
  521. # TestDataFrameGroupByPlots.test_grouped_box_multiple_axes
  522. fig, axes = self.plt.subplots(2, 2)
  523. with warnings.catch_warnings():
  524. warnings.simplefilter("ignore", UserWarning)
  525. df = DataFrame(np.random.rand(10, 4),
  526. index=list(string.ascii_letters[:10]))
  527. returned = df.plot(subplots=True, ax=axes, layout=(2, 1),
  528. sharex=False, sharey=False)
  529. self._check_axes_shape(returned, axes_num=4, layout=(2, 2))
  530. assert returned.shape == (4, )
  531. returned = df.plot(subplots=True, ax=axes, layout=(2, -1),
  532. sharex=False, sharey=False)
  533. self._check_axes_shape(returned, axes_num=4, layout=(2, 2))
  534. assert returned.shape == (4, )
  535. returned = df.plot(subplots=True, ax=axes, layout=(-1, 2),
  536. sharex=False, sharey=False)
  537. self._check_axes_shape(returned, axes_num=4, layout=(2, 2))
  538. assert returned.shape == (4, )
  539. # single column
  540. fig, axes = self.plt.subplots(1, 1)
  541. df = DataFrame(np.random.rand(10, 1),
  542. index=list(string.ascii_letters[:10]))
  543. axes = df.plot(subplots=True, ax=[axes], sharex=False, sharey=False)
  544. self._check_axes_shape(axes, axes_num=1, layout=(1, 1))
  545. assert axes.shape == (1, )
  546. def test_subplots_ts_share_axes(self):
  547. # GH 3964
  548. fig, axes = self.plt.subplots(3, 3, sharex=True, sharey=True)
  549. self.plt.subplots_adjust(left=0.05, right=0.95, hspace=0.3, wspace=0.3)
  550. df = DataFrame(
  551. np.random.randn(10, 9),
  552. index=date_range(start='2014-07-01', freq='M', periods=10))
  553. for i, ax in enumerate(axes.ravel()):
  554. df[i].plot(ax=ax, fontsize=5)
  555. # Rows other than bottom should not be visible
  556. for ax in axes[0:-1].ravel():
  557. self._check_visible(ax.get_xticklabels(), visible=False)
  558. # Bottom row should be visible
  559. for ax in axes[-1].ravel():
  560. self._check_visible(ax.get_xticklabels(), visible=True)
  561. # First column should be visible
  562. for ax in axes[[0, 1, 2], [0]].ravel():
  563. self._check_visible(ax.get_yticklabels(), visible=True)
  564. # Other columns should not be visible
  565. for ax in axes[[0, 1, 2], [1]].ravel():
  566. self._check_visible(ax.get_yticklabels(), visible=False)
  567. for ax in axes[[0, 1, 2], [2]].ravel():
  568. self._check_visible(ax.get_yticklabels(), visible=False)
  569. def test_subplots_sharex_axes_existing_axes(self):
  570. # GH 9158
  571. d = {'A': [1., 2., 3., 4.], 'B': [4., 3., 2., 1.], 'C': [5, 1, 3, 4]}
  572. df = DataFrame(d, index=date_range('2014 10 11', '2014 10 14'))
  573. axes = df[['A', 'B']].plot(subplots=True)
  574. df['C'].plot(ax=axes[0], secondary_y=True)
  575. self._check_visible(axes[0].get_xticklabels(), visible=False)
  576. self._check_visible(axes[1].get_xticklabels(), visible=True)
  577. for ax in axes.ravel():
  578. self._check_visible(ax.get_yticklabels(), visible=True)
  579. @pytest.mark.slow
  580. def test_subplots_dup_columns(self):
  581. # GH 10962
  582. df = DataFrame(np.random.rand(5, 5), columns=list('aaaaa'))
  583. axes = df.plot(subplots=True)
  584. for ax in axes:
  585. self._check_legend_labels(ax, labels=['a'])
  586. assert len(ax.lines) == 1
  587. tm.close()
  588. axes = df.plot(subplots=True, secondary_y='a')
  589. for ax in axes:
  590. # (right) is only attached when subplots=False
  591. self._check_legend_labels(ax, labels=['a'])
  592. assert len(ax.lines) == 1
  593. tm.close()
  594. ax = df.plot(secondary_y='a')
  595. self._check_legend_labels(ax, labels=['a (right)'] * 5)
  596. assert len(ax.lines) == 0
  597. assert len(ax.right_ax.lines) == 5
  598. def test_negative_log(self):
  599. df = - DataFrame(rand(6, 4),
  600. index=list(string.ascii_letters[:6]),
  601. columns=['x', 'y', 'z', 'four'])
  602. with pytest.raises(ValueError):
  603. df.plot.area(logy=True)
  604. with pytest.raises(ValueError):
  605. df.plot.area(loglog=True)
  606. def _compare_stacked_y_cood(self, normal_lines, stacked_lines):
  607. base = np.zeros(len(normal_lines[0].get_data()[1]))
  608. for nl, sl in zip(normal_lines, stacked_lines):
  609. base += nl.get_data()[1] # get y coordinates
  610. sy = sl.get_data()[1]
  611. tm.assert_numpy_array_equal(base, sy)
  612. def test_line_area_stacked(self):
  613. with tm.RNGContext(42):
  614. df = DataFrame(rand(6, 4), columns=['w', 'x', 'y', 'z'])
  615. neg_df = -df
  616. # each column has either positive or negative value
  617. sep_df = DataFrame({'w': rand(6),
  618. 'x': rand(6),
  619. 'y': -rand(6),
  620. 'z': -rand(6)})
  621. # each column has positive-negative mixed value
  622. mixed_df = DataFrame(randn(6, 4),
  623. index=list(string.ascii_letters[:6]),
  624. columns=['w', 'x', 'y', 'z'])
  625. for kind in ['line', 'area']:
  626. ax1 = _check_plot_works(df.plot, kind=kind, stacked=False)
  627. ax2 = _check_plot_works(df.plot, kind=kind, stacked=True)
  628. self._compare_stacked_y_cood(ax1.lines, ax2.lines)
  629. ax1 = _check_plot_works(neg_df.plot, kind=kind, stacked=False)
  630. ax2 = _check_plot_works(neg_df.plot, kind=kind, stacked=True)
  631. self._compare_stacked_y_cood(ax1.lines, ax2.lines)
  632. ax1 = _check_plot_works(sep_df.plot, kind=kind, stacked=False)
  633. ax2 = _check_plot_works(sep_df.plot, kind=kind, stacked=True)
  634. self._compare_stacked_y_cood(ax1.lines[:2], ax2.lines[:2])
  635. self._compare_stacked_y_cood(ax1.lines[2:], ax2.lines[2:])
  636. _check_plot_works(mixed_df.plot, stacked=False)
  637. with pytest.raises(ValueError):
  638. mixed_df.plot(stacked=True)
  639. _check_plot_works(df.plot, kind=kind, logx=True, stacked=True)
  640. def test_line_area_nan_df(self):
  641. values1 = [1, 2, np.nan, 3]
  642. values2 = [3, np.nan, 2, 1]
  643. df = DataFrame({'a': values1, 'b': values2})
  644. tdf = DataFrame({'a': values1,
  645. 'b': values2}, index=tm.makeDateIndex(k=4))
  646. for d in [df, tdf]:
  647. ax = _check_plot_works(d.plot)
  648. masked1 = ax.lines[0].get_ydata()
  649. masked2 = ax.lines[1].get_ydata()
  650. # remove nan for comparison purpose
  651. exp = np.array([1, 2, 3], dtype=np.float64)
  652. tm.assert_numpy_array_equal(np.delete(masked1.data, 2), exp)
  653. exp = np.array([3, 2, 1], dtype=np.float64)
  654. tm.assert_numpy_array_equal(np.delete(masked2.data, 1), exp)
  655. tm.assert_numpy_array_equal(
  656. masked1.mask, np.array([False, False, True, False]))
  657. tm.assert_numpy_array_equal(
  658. masked2.mask, np.array([False, True, False, False]))
  659. expected1 = np.array([1, 2, 0, 3], dtype=np.float64)
  660. expected2 = np.array([3, 0, 2, 1], dtype=np.float64)
  661. ax = _check_plot_works(d.plot, stacked=True)
  662. tm.assert_numpy_array_equal(ax.lines[0].get_ydata(), expected1)
  663. tm.assert_numpy_array_equal(ax.lines[1].get_ydata(),
  664. expected1 + expected2)
  665. ax = _check_plot_works(d.plot.area)
  666. tm.assert_numpy_array_equal(ax.lines[0].get_ydata(), expected1)
  667. tm.assert_numpy_array_equal(ax.lines[1].get_ydata(),
  668. expected1 + expected2)
  669. ax = _check_plot_works(d.plot.area, stacked=False)
  670. tm.assert_numpy_array_equal(ax.lines[0].get_ydata(), expected1)
  671. tm.assert_numpy_array_equal(ax.lines[1].get_ydata(), expected2)
  672. def test_line_lim(self):
  673. df = DataFrame(rand(6, 3), columns=['x', 'y', 'z'])
  674. ax = df.plot()
  675. xmin, xmax = ax.get_xlim()
  676. lines = ax.get_lines()
  677. assert xmin <= lines[0].get_data()[0][0]
  678. assert xmax >= lines[0].get_data()[0][-1]
  679. ax = df.plot(secondary_y=True)
  680. xmin, xmax = ax.get_xlim()
  681. lines = ax.get_lines()
  682. assert xmin <= lines[0].get_data()[0][0]
  683. assert xmax >= lines[0].get_data()[0][-1]
  684. axes = df.plot(secondary_y=True, subplots=True)
  685. self._check_axes_shape(axes, axes_num=3, layout=(3, 1))
  686. for ax in axes:
  687. assert hasattr(ax, 'left_ax')
  688. assert not hasattr(ax, 'right_ax')
  689. xmin, xmax = ax.get_xlim()
  690. lines = ax.get_lines()
  691. assert xmin <= lines[0].get_data()[0][0]
  692. assert xmax >= lines[0].get_data()[0][-1]
  693. def test_area_lim(self):
  694. df = DataFrame(rand(6, 4), columns=['x', 'y', 'z', 'four'])
  695. neg_df = -df
  696. for stacked in [True, False]:
  697. ax = _check_plot_works(df.plot.area, stacked=stacked)
  698. xmin, xmax = ax.get_xlim()
  699. ymin, ymax = ax.get_ylim()
  700. lines = ax.get_lines()
  701. assert xmin <= lines[0].get_data()[0][0]
  702. assert xmax >= lines[0].get_data()[0][-1]
  703. assert ymin == 0
  704. ax = _check_plot_works(neg_df.plot.area, stacked=stacked)
  705. ymin, ymax = ax.get_ylim()
  706. assert ymax == 0
  707. @pytest.mark.slow
  708. def test_bar_colors(self):
  709. import matplotlib.pyplot as plt
  710. default_colors = self._unpack_cycler(plt.rcParams)
  711. df = DataFrame(randn(5, 5))
  712. ax = df.plot.bar()
  713. self._check_colors(ax.patches[::5], facecolors=default_colors[:5])
  714. tm.close()
  715. custom_colors = 'rgcby'
  716. ax = df.plot.bar(color=custom_colors)
  717. self._check_colors(ax.patches[::5], facecolors=custom_colors)
  718. tm.close()
  719. from matplotlib import cm
  720. # Test str -> colormap functionality
  721. ax = df.plot.bar(colormap='jet')
  722. rgba_colors = lmap(cm.jet, np.linspace(0, 1, 5))
  723. self._check_colors(ax.patches[::5], facecolors=rgba_colors)
  724. tm.close()
  725. # Test colormap functionality
  726. ax = df.plot.bar(colormap=cm.jet)
  727. rgba_colors = lmap(cm.jet, np.linspace(0, 1, 5))
  728. self._check_colors(ax.patches[::5], facecolors=rgba_colors)
  729. tm.close()
  730. ax = df.loc[:, [0]].plot.bar(color='DodgerBlue')
  731. self._check_colors([ax.patches[0]], facecolors=['DodgerBlue'])
  732. tm.close()
  733. ax = df.plot(kind='bar', color='green')
  734. self._check_colors(ax.patches[::5], facecolors=['green'] * 5)
  735. tm.close()
  736. def test_bar_user_colors(self):
  737. df = pd.DataFrame({"A": range(4),
  738. "B": range(1, 5),
  739. "color": ['red', 'blue', 'blue', 'red']})
  740. # This should *only* work when `y` is specified, else
  741. # we use one color per column
  742. ax = df.plot.bar(y='A', color=df['color'])
  743. result = [p.get_facecolor() for p in ax.patches]
  744. expected = [(1., 0., 0., 1.),
  745. (0., 0., 1., 1.),
  746. (0., 0., 1., 1.),
  747. (1., 0., 0., 1.)]
  748. assert result == expected
  749. @pytest.mark.slow
  750. def test_bar_linewidth(self):
  751. df = DataFrame(randn(5, 5))
  752. # regular
  753. ax = df.plot.bar(linewidth=2)
  754. for r in ax.patches:
  755. assert r.get_linewidth() == 2
  756. # stacked
  757. ax = df.plot.bar(stacked=True, linewidth=2)
  758. for r in ax.patches:
  759. assert r.get_linewidth() == 2
  760. # subplots
  761. axes = df.plot.bar(linewidth=2, subplots=True)
  762. self._check_axes_shape(axes, axes_num=5, layout=(5, 1))
  763. for ax in axes:
  764. for r in ax.patches:
  765. assert r.get_linewidth() == 2
  766. @pytest.mark.slow
  767. def test_bar_barwidth(self):
  768. df = DataFrame(randn(5, 5))
  769. width = 0.9
  770. # regular
  771. ax = df.plot.bar(width=width)
  772. for r in ax.patches:
  773. assert r.get_width() == width / len(df.columns)
  774. # stacked
  775. ax = df.plot.bar(stacked=True, width=width)
  776. for r in ax.patches:
  777. assert r.get_width() == width
  778. # horizontal regular
  779. ax = df.plot.barh(width=width)
  780. for r in ax.patches:
  781. assert r.get_height() == width / len(df.columns)
  782. # horizontal stacked
  783. ax = df.plot.barh(stacked=True, width=width)
  784. for r in ax.patches:
  785. assert r.get_height() == width
  786. # subplots
  787. axes = df.plot.bar(width=width, subplots=True)
  788. for ax in axes:
  789. for r in ax.patches:
  790. assert r.get_width() == width
  791. # horizontal subplots
  792. axes = df.plot.barh(width=width, subplots=True)
  793. for ax in axes:
  794. for r in ax.patches:
  795. assert r.get_height() == width
  796. @pytest.mark.slow
  797. def test_bar_barwidth_position(self):
  798. df = DataFrame(randn(5, 5))
  799. self._check_bar_alignment(df, kind='bar', stacked=False, width=0.9,
  800. position=0.2)
  801. self._check_bar_alignment(df, kind='bar', stacked=True, width=0.9,
  802. position=0.2)
  803. self._check_bar_alignment(df, kind='barh', stacked=False, width=0.9,
  804. position=0.2)
  805. self._check_bar_alignment(df, kind='barh', stacked=True, width=0.9,
  806. position=0.2)
  807. self._check_bar_alignment(df, kind='bar', subplots=True, width=0.9,
  808. position=0.2)
  809. self._check_bar_alignment(df, kind='barh', subplots=True, width=0.9,
  810. position=0.2)
  811. @pytest.mark.slow
  812. def test_bar_barwidth_position_int(self):
  813. # GH 12979
  814. df = DataFrame(randn(5, 5))
  815. for w in [1, 1.]:
  816. ax = df.plot.bar(stacked=True, width=w)
  817. ticks = ax.xaxis.get_ticklocs()
  818. tm.assert_numpy_array_equal(ticks, np.array([0, 1, 2, 3, 4]))
  819. assert ax.get_xlim() == (-0.75, 4.75)
  820. # check left-edge of bars
  821. assert ax.patches[0].get_x() == -0.5
  822. assert ax.patches[-1].get_x() == 3.5
  823. self._check_bar_alignment(df, kind='bar', stacked=True, width=1)
  824. self._check_bar_alignment(df, kind='barh', stacked=False, width=1)
  825. self._check_bar_alignment(df, kind='barh', stacked=True, width=1)
  826. self._check_bar_alignment(df, kind='bar', subplots=True, width=1)
  827. self._check_bar_alignment(df, kind='barh', subplots=True, width=1)
  828. @pytest.mark.slow
  829. def test_bar_bottom_left(self):
  830. df = DataFrame(rand(5, 5))
  831. ax = df.plot.bar(stacked=False, bottom=1)
  832. result = [p.get_y() for p in ax.patches]
  833. assert result == [1] * 25
  834. ax = df.plot.bar(stacked=True, bottom=[-1, -2, -3, -4, -5])
  835. result = [p.get_y() for p in ax.patches[:5]]
  836. assert result == [-1, -2, -3, -4, -5]
  837. ax = df.plot.barh(stacked=False, left=np.array([1, 1, 1, 1, 1]))
  838. result = [p.get_x() for p in ax.patches]
  839. assert result == [1] * 25
  840. ax = df.plot.barh(stacked=True, left=[1, 2, 3, 4, 5])
  841. result = [p.get_x() for p in ax.patches[:5]]
  842. assert result == [1, 2, 3, 4, 5]
  843. axes = df.plot.bar(subplots=True, bottom=-1)
  844. for ax in axes:
  845. result = [p.get_y() for p in ax.patches]
  846. assert result == [-1] * 5
  847. axes = df.plot.barh(subplots=True, left=np.array([1, 1, 1, 1, 1]))
  848. for ax in axes:
  849. result = [p.get_x() for p in ax.patches]
  850. assert result == [1] * 5
  851. @pytest.mark.slow
  852. def test_bar_nan(self):
  853. df = DataFrame({'A': [10, np.nan, 20],
  854. 'B': [5, 10, 20],
  855. 'C': [1, 2, 3]})
  856. ax = df.plot.bar()
  857. expected = [10, 0, 20, 5, 10, 20, 1, 2, 3]
  858. result = [p.get_height() for p in ax.patches]
  859. assert result == expected
  860. ax = df.plot.bar(stacked=True)
  861. result = [p.get_height() for p in ax.patches]
  862. assert result == expected
  863. result = [p.get_y() for p in ax.patches]
  864. expected = [0.0, 0.0, 0.0, 10.0, 0.0, 20.0, 15.0, 10.0, 40.0]
  865. assert result == expected
  866. @pytest.mark.slow
  867. def test_bar_categorical(self):
  868. # GH 13019
  869. df1 = pd.DataFrame(np.random.randn(6, 5),
  870. index=pd.Index(list('ABCDEF')),
  871. columns=pd.Index(list('abcde')))
  872. # categorical index must behave the same
  873. df2 = pd.DataFrame(np.random.randn(6, 5),
  874. index=pd.CategoricalIndex(list('ABCDEF')),
  875. columns=pd.CategoricalIndex(list('abcde')))
  876. for df in [df1, df2]:
  877. ax = df.plot.bar()
  878. ticks = ax.xaxis.get_ticklocs()
  879. tm.assert_numpy_array_equal(ticks, np.array([0, 1, 2, 3, 4, 5]))
  880. assert ax.get_xlim() == (-0.5, 5.5)
  881. # check left-edge of bars
  882. assert ax.patches[0].get_x() == -0.25
  883. assert ax.patches[-1].get_x() == 5.15
  884. ax = df.plot.bar(stacked=True)
  885. tm.assert_numpy_array_equal(ticks, np.array([0, 1, 2, 3, 4, 5]))
  886. assert ax.get_xlim() == (-0.5, 5.5)
  887. assert ax.patches[0].get_x() == -0.25
  888. assert ax.patches[-1].get_x() == 4.75
  889. @pytest.mark.slow
  890. def test_plot_scatter(self):
  891. df = DataFrame(randn(6, 4),
  892. index=list(string.ascii_letters[:6]),
  893. columns=['x', 'y', 'z', 'four'])
  894. _check_plot_works(df.plot.scatter, x='x', y='y')
  895. _check_plot_works(df.plot.scatter, x=1, y=2)
  896. with pytest.raises(TypeError):
  897. df.plot.scatter(x='x')
  898. with pytest.raises(TypeError):
  899. df.plot.scatter(y='y')
  900. # GH 6951
  901. axes = df.plot(x='x', y='y', kind='scatter', subplots=True)
  902. self._check_axes_shape(axes, axes_num=1, layout=(1, 1))
  903. @pytest.mark.slow
  904. def test_if_scatterplot_colorbar_affects_xaxis_visibility(self):
  905. # addressing issue #10611, to ensure colobar does not
  906. # interfere with x-axis label and ticklabels with
  907. # ipython inline backend.
  908. random_array = np.random.random((1000, 3))
  909. df = pd.DataFrame(random_array,
  910. columns=['A label', 'B label', 'C label'])
  911. ax1 = df.plot.scatter(x='A label', y='B label')
  912. ax2 = df.plot.scatter(x='A label', y='B label', c='C label')
  913. vis1 = [vis.get_visible() for vis in
  914. ax1.xaxis.get_minorticklabels()]
  915. vis2 = [vis.get_visible() for vis in
  916. ax2.xaxis.get_minorticklabels()]
  917. assert vis1 == vis2
  918. vis1 = [vis.get_visible() for vis in
  919. ax1.xaxis.get_majorticklabels()]
  920. vis2 = [vis.get_visible() for vis in
  921. ax2.xaxis.get_majorticklabels()]
  922. assert vis1 == vis2
  923. assert (ax1.xaxis.get_label().get_visible() ==
  924. ax2.xaxis.get_label().get_visible())
  925. @pytest.mark.slow
  926. def test_if_hexbin_xaxis_label_is_visible(self):
  927. # addressing issue #10678, to ensure colobar does not
  928. # interfere with x-axis label and ticklabels with
  929. # ipython inline backend.
  930. random_array = np.random.random((1000, 3))
  931. df = pd.DataFrame(random_array,
  932. columns=['A label', 'B label', 'C label'])
  933. ax = df.plot.hexbin('A label', 'B label', gridsize=12)
  934. assert all(vis.get_visible() for vis in
  935. ax.xaxis.get_minorticklabels())
  936. assert all(vis.get_visible() for vis in
  937. ax.xaxis.get_majorticklabels())
  938. assert ax.xaxis.get_label().get_visible()
  939. @pytest.mark.slow
  940. def test_if_scatterplot_colorbars_are_next_to_parent_axes(self):
  941. import matplotlib.pyplot as plt
  942. random_array = np.random.random((1000, 3))
  943. df = pd.DataFrame(random_array,
  944. columns=['A label', 'B label', 'C label'])
  945. fig, axes = plt.subplots(1, 2)
  946. df.plot.scatter('A label', 'B label', c='C label', ax=axes[0])
  947. df.plot.scatter('A label', 'B label', c='C label', ax=axes[1])
  948. plt.tight_layout()
  949. points = np.array([ax.get_position().get_points()
  950. for ax in fig.axes])
  951. axes_x_coords = points[:, :, 0]
  952. parent_distance = axes_x_coords[1, :] - axes_x_coords[0, :]
  953. colorbar_distance = axes_x_coords[3, :] - axes_x_coords[2, :]
  954. assert np.isclose(parent_distance,
  955. colorbar_distance, atol=1e-7).all()
  956. @pytest.mark.slow
  957. def test_plot_scatter_with_categorical_data(self):
  958. # GH 16199
  959. df = pd.DataFrame({'x': [1, 2, 3, 4],
  960. 'y': pd.Categorical(['a', 'b', 'a', 'c'])})
  961. with pytest.raises(ValueError) as ve:
  962. df.plot(x='x', y='y', kind='scatter')
  963. ve.match('requires y column to be numeric')
  964. with pytest.raises(ValueError) as ve:
  965. df.plot(x='y', y='x', kind='scatter')
  966. ve.match('requires x column to be numeric')
  967. with pytest.raises(ValueError) as ve:
  968. df.plot(x='y', y='y', kind='scatter')
  969. ve.match('requires x column to be numeric')
  970. @pytest.mark.slow
  971. def test_plot_scatter_with_c(self):
  972. df = DataFrame(randn(6, 4),
  973. index=list(string.ascii_letters[:6]),
  974. columns=['x', 'y', 'z', 'four'])
  975. axes = [df.plot.scatter(x='x', y='y', c='z'),
  976. df.plot.scatter(x=0, y=1, c=2)]
  977. for ax in axes:
  978. # default to Greys
  979. assert ax.collections[0].cmap.name == 'Greys'
  980. # n.b. there appears to be no public method
  981. # to get the colorbar label
  982. assert ax.collections[0].colorbar._label == 'z'
  983. cm = 'cubehelix'
  984. ax = df.plot.scatter(x='x', y='y', c='z', colormap=cm)
  985. assert ax.collections[0].cmap.name == cm
  986. # verify turning off colorbar works
  987. ax = df.plot.scatter(x='x', y='y', c='z', colorbar=False)
  988. assert ax.collections[0].colorbar is None
  989. # verify that we can still plot a solid color
  990. ax = df.plot.scatter(x=0, y=1, c='red')
  991. assert ax.collections[0].colorbar is None
  992. self._check_colors(ax.collections, facecolors=['r'])
  993. # Ensure that we can pass an np.array straight through to matplotlib,
  994. # this functionality was accidentally removed previously.
  995. # See https://github.com/pandas-dev/pandas/issues/8852 for bug report
  996. #
  997. # Exercise colormap path and non-colormap path as they are independent
  998. #
  999. df = DataFrame({'A': [1, 2], 'B': [3, 4]})
  1000. red_rgba = [1.0, 0.0, 0.0, 1.0]
  1001. green_rgba = [0.0, 1.0, 0.0, 1.0]
  1002. rgba_array = np.array([red_rgba, green_rgba])
  1003. ax = df.plot.scatter(x='A', y='B', c=rgba_array)
  1004. # expect the face colors of the points in the non-colormap path to be
  1005. # identical to the values we supplied, normally we'd be on shaky ground
  1006. # comparing floats for equality but here we expect them to be
  1007. # identical.
  1008. tm.assert_numpy_array_equal(ax.collections[0]
  1009. .get_facecolor(), rgba_array)
  1010. # we don't test the colors of the faces in this next plot because they
  1011. # are dependent on the spring colormap, which may change its colors
  1012. # later.
  1013. float_array = np.array([0.0, 1.0])
  1014. df.plot.scatter(x='A', y='B', c=float_array, cmap='spring')
  1015. def test_scatter_colors(self):
  1016. df = DataFrame({'a': [1, 2, 3], 'b': [1, 2, 3], 'c': [1, 2, 3]})
  1017. with pytest.raises(TypeError):
  1018. df.plot.scatter(x='a', y='b', c='c', color='green')
  1019. default_colors = self._unpack_cycler(self.plt.rcParams)
  1020. ax = df.plot.scatter(x='a', y='b', c='c')
  1021. tm.assert_numpy_array_equal(
  1022. ax.collections[0].get_facecolor()[0],
  1023. np.array(self.colorconverter.to_rgba(default_colors[0])))
  1024. ax = df.plot.scatter(x='a', y='b', color='white')
  1025. tm.assert_numpy_array_equal(ax.collections[0].get_facecolor()[0],
  1026. np.array([1, 1, 1, 1], dtype=np.float64))
  1027. @pytest.mark.slow
  1028. def test_plot_bar(self):
  1029. df = DataFrame(randn(6, 4),
  1030. index=list(string.ascii_letters[:6]),
  1031. columns=['one', 'two', 'three', 'four'])
  1032. _check_plot_works(df.plot.bar)
  1033. _check_plot_works(df.plot.bar, legend=False)
  1034. # _check_plot_works adds an ax so catch warning. see GH #13188
  1035. with tm.assert_produces_warning(UserWarning):
  1036. _check_plot_works(df.plot.bar, subplots=True)
  1037. _check_plot_works(df.plot.bar, stacked=True)
  1038. df = DataFrame(randn(10, 15),
  1039. index=list(string.ascii_letters[:10]),
  1040. columns=lrange(15))
  1041. _check_plot_works(df.plot.bar)
  1042. df = DataFrame({'a': [0, 1], 'b': [1, 0]})
  1043. ax = _check_plot_works(df.plot.bar)
  1044. self._check_ticks_props(ax, xrot=90)
  1045. ax = df.plot.bar(rot=35, fontsize=10)
  1046. self._check_ticks_props(ax, xrot=35, xlabelsize=10, ylabelsize=10)
  1047. ax = _check_plot_works(df.plot.barh)
  1048. self._check_ticks_props(ax, yrot=0)
  1049. ax = df.plot.barh(rot=55, fontsize=11)
  1050. self._check_ticks_props(ax, yrot=55, ylabelsize=11, xlabelsize=11)
  1051. def _check_bar_alignment(self, df, kind='bar', stacked=False,
  1052. subplots=False, align='center', width=0.5,
  1053. position=0.5):
  1054. axes = df.plot(kind=kind, stacked=stacked, subplots=subplots,
  1055. align=align, width=width, position=position, grid=True)
  1056. axes = self._flatten_visible(axes)
  1057. for ax in axes:
  1058. if kind == 'bar':
  1059. axis = ax.xaxis
  1060. ax_min, ax_max = ax.get_xlim()
  1061. min_edge = min(p.get_x() for p in ax.patches)
  1062. max_edge = max(p.get_x() + p.get_width() for p in ax.patches)
  1063. elif kind == 'barh':
  1064. axis = ax.yaxis
  1065. ax_min, ax_max = ax.get_ylim()
  1066. min_edge = min(p.get_y() for p in ax.patches)
  1067. max_edge = max(p.get_y() + p.get_height() for p in ax.patches)
  1068. else:
  1069. raise ValueError
  1070. # GH 7498
  1071. # compare margins between lim and bar edges
  1072. tm.assert_almost_equal(ax_min, min_edge - 0.25)
  1073. tm.assert_almost_equal(ax_max, max_edge + 0.25)
  1074. p = ax.patches[0]
  1075. if kind == 'bar' and (stacked is True or subplots is True):
  1076. edge = p.get_x()
  1077. center = edge + p.get_width() * position
  1078. elif kind == 'bar' and stacked is False:
  1079. center = p.get_x() + p.get_width() * len(df.columns) * position
  1080. edge = p.get_x()
  1081. elif kind == 'barh' and (stacked is True or subplots is True):
  1082. center = p.get_y() + p.get_height() * position
  1083. edge = p.get_y()
  1084. elif kind == 'barh' and stacked is False:
  1085. center = p.get_y() + p.get_height() * len(
  1086. df.columns) * position
  1087. edge = p.get_y()
  1088. else:
  1089. raise ValueError
  1090. # Check the ticks locates on integer
  1091. assert (axis.get_ticklocs() == np.arange(len(df))).all()
  1092. if align == 'center':
  1093. # Check whether the bar locates on center
  1094. tm.assert_almost_equal(axis.get_ticklocs()[0], center)
  1095. elif align == 'edge':
  1096. # Check whether the bar's edge starts from the tick
  1097. tm.assert_almost_equal(axis.get_ticklocs()[0], edge)
  1098. else:
  1099. raise ValueError
  1100. return axes
  1101. @pytest.mark.slow
  1102. def test_bar_stacked_center(self):
  1103. # GH2157
  1104. df = DataFrame({'A': [3] * 5, 'B': lrange(5)}, index=lrange(5))
  1105. self._check_bar_alignment(df, kind='bar', stacked=True)
  1106. self._check_bar_alignment(df, kind='bar', stacked=True, width=0.9)
  1107. self._check_bar_alignment(df, kind='barh', stacked=True)
  1108. self._check_bar_alignment(df, kind='barh', stacked=True, width=0.9)
  1109. @pytest.mark.slow
  1110. def test_bar_center(self):
  1111. df = DataFrame({'A': [3] * 5, 'B': lrange(5)}, index=lrange(5))
  1112. self._check_bar_alignment(df, kind='bar', stacked=False)
  1113. self._check_bar_alignment(df, kind='bar', stacked=False, width=0.9)
  1114. self._check_bar_alignment(df, kind='barh', stacked=False)
  1115. self._check_bar_alignment(df, kind='barh', stacked=False, width=0.9)
  1116. @pytest.mark.slow
  1117. def test_bar_subplots_center(self):
  1118. df = DataFrame({'A': [3] * 5, 'B': lrange(5)}, index=lrange(5))
  1119. self._check_bar_alignment(df, kind='bar', subplots=True)
  1120. self._check_bar_alignment(df, kind='bar', subplots=True, width=0.9)
  1121. self._check_bar_alignment(df, kind='barh', subplots=True)
  1122. self._check_bar_alignment(df, kind='barh', subplots=True, width=0.9)
  1123. @pytest.mark.slow
  1124. def test_bar_align_single_column(self):
  1125. df = DataFrame(randn(5))
  1126. self._check_bar_alignment(df, kind='bar', stacked=False)
  1127. self._check_bar_alignment(df, kind='bar', stacked=True)
  1128. self._check_bar_alignment(df, kind='barh', stacked=False)
  1129. self._check_bar_alignment(df, kind='barh', stacked=True)
  1130. self._check_bar_alignment(df, kind='bar', subplots=True)
  1131. self._check_bar_alignment(df, kind='barh', subplots=True)
  1132. @pytest.mark.slow
  1133. def test_bar_edge(self):
  1134. df = DataFrame({'A': [3] * 5, 'B': lrange(5)}, index=lrange(5))
  1135. self._check_bar_alignment(df, kind='bar', stacked=True, align='edge')
  1136. self._check_bar_alignment(df, kind='bar', stacked=True, width=0.9,
  1137. align='edge')
  1138. self._check_bar_alignment(df, kind='barh', stacked=True, align='edge')
  1139. self._check_bar_alignment(df, kind='barh', stacked=True, width=0.9,
  1140. align='edge')
  1141. self._check_bar_alignment(df, kind='bar', stacked=False, align='edge')
  1142. self._check_bar_alignment(df, kind='bar', stacked=False, width=0.9,
  1143. align='edge')
  1144. self._check_bar_alignment(df, kind='barh', stacked=False, align='edge')
  1145. self._check_bar_alignment(df, kind='barh', stacked=False, width=0.9,
  1146. align='edge')
  1147. self._check_bar_alignment(df, kind='bar', subplots=True, align='edge')
  1148. self._check_bar_alignment(df, kind='bar', subplots=True, width=0.9,
  1149. align='edge')
  1150. self._check_bar_alignment(df, kind='barh', subplots=True, align='edge')
  1151. self._check_bar_alignment(df, kind='barh', subplots=True, width=0.9,
  1152. align='edge')
  1153. @pytest.mark.slow
  1154. def test_bar_log_no_subplots(self):
  1155. # GH3254, GH3298 matplotlib/matplotlib#1882, #1892
  1156. # regressions in 1.2.1
  1157. expected = np.array([.1, 1., 10., 100])
  1158. # no subplots
  1159. df = DataFrame({'A': [3] * 5, 'B': lrange(1, 6)}, index=lrange(5))
  1160. ax = df.plot.bar(grid=True, log=True)
  1161. tm.assert_numpy_array_equal(ax.yaxis.get_ticklocs(), expected)
  1162. @pytest.mark.slow
  1163. def test_bar_log_subplots(self):
  1164. expected = np.array([.1, 1., 10., 100., 1000., 1e4])
  1165. ax = DataFrame([Series([200, 300]), Series([300, 500])]).plot.bar(
  1166. log=True, subplots=True)
  1167. tm.assert_numpy_array_equal(ax[0].yaxis.get_ticklocs(), expected)
  1168. tm.assert_numpy_array_equal(ax[1].yaxis.get_ticklocs(), expected)
  1169. @pytest.mark.slow
  1170. def test_boxplot(self):
  1171. df = self.hist_df
  1172. series = df['height']
  1173. numeric_cols = df._get_numeric_data().columns
  1174. labels = [pprint_thing(c) for c in numeric_cols]
  1175. ax = _check_plot_works(df.plot.box)
  1176. self._check_text_labels(ax.get_xticklabels(), labels)
  1177. tm.assert_numpy_array_equal(ax.xaxis.get_ticklocs(),
  1178. np.arange(1, len(numeric_cols) + 1))
  1179. assert len(ax.lines) == self.bp_n_objects * len(numeric_cols)
  1180. # different warning on py3
  1181. if not PY3:
  1182. with tm.assert_produces_warning(UserWarning):
  1183. axes = _check_plot_works(df.plot.box, subplots=True, logy=True)
  1184. self._check_axes_shape(axes, axes_num=3, layout=(1, 3))
  1185. self._check_ax_scales(axes, yaxis='log')
  1186. for ax, label in zip(axes, labels):
  1187. self._check_text_labels(ax.get_xticklabels(), [label])
  1188. assert len(ax.lines) == self.bp_n_objects
  1189. axes = series.plot.box(rot=40)
  1190. self._check_ticks_props(axes, xrot=40, yrot=0)
  1191. tm.close()
  1192. ax = _check_plot_works(series.plot.box)
  1193. positions = np.array([1, 6, 7])
  1194. ax = df.plot.box(positions=positions)
  1195. numeric_cols = df._get_numeric_data().columns
  1196. labels = [pprint_thing(c) for c in numeric_cols]
  1197. self._check_text_labels(ax.get_xticklabels(), labels)
  1198. tm.assert_numpy_array_equal(ax.xaxis.get_ticklocs(), positions)
  1199. assert len(ax.lines) == self.bp_n_objects * len(numeric_cols)
  1200. @pytest.mark.slow
  1201. def test_boxplot_vertical(self):
  1202. df = self.hist_df
  1203. numeric_cols = df._get_numeric_data().columns
  1204. labels = [pprint_thing(c) for c in numeric_cols]
  1205. # if horizontal, yticklabels are rotated
  1206. ax = df.plot.box(rot=50, fontsize=8, vert=False)
  1207. self._check_ticks_props(ax, xrot=0, yrot=50, ylabelsize=8)
  1208. self._check_text_labels(ax.get_yticklabels(), labels)
  1209. assert len(ax.lines) == self.bp_n_objects * len(numeric_cols)
  1210. # _check_plot_works adds an ax so catch warning. see GH #13188
  1211. with tm.assert_produces_warning(UserWarning):
  1212. axes = _check_plot_works(df.plot.box,
  1213. subplots=True, vert=False, logx=True)
  1214. self._check_axes_shape(axes, axes_num=3, layout=(1, 3))
  1215. self._check_ax_scales(axes, xaxis='log')
  1216. for ax, label in zip(axes, labels):
  1217. self._check_text_labels(ax.get_yticklabels(), [label])
  1218. assert len(ax.lines) == self.bp_n_objects
  1219. positions = np.array([3, 2, 8])
  1220. ax = df.plot.box(positions=positions, vert=False)
  1221. self._check_text_labels(ax.get_yticklabels(), labels)
  1222. tm.assert_numpy_array_equal(ax.yaxis.get_ticklocs(), positions)
  1223. assert len(ax.lines) == self.bp_n_objects * len(numeric_cols)
  1224. @pytest.mark.slow
  1225. def test_boxplot_return_type(self):
  1226. df = DataFrame(randn(6, 4),
  1227. index=list(string.ascii_letters[:6]),
  1228. columns=['one', 'two', 'three', 'four'])
  1229. with pytest.raises(ValueError):
  1230. df.plot.box(return_type='NOTATYPE')
  1231. result = df.plot.box(return_type='dict')
  1232. self._check_box_return_type(result, 'dict')
  1233. result = df.plot.box(return_type='axes')
  1234. self._check_box_return_type(result, 'axes')
  1235. result = df.plot.box() # default axes
  1236. self._check_box_return_type(result, 'axes')
  1237. result = df.plot.box(return_type='both')
  1238. self._check_box_return_type(result, 'both')
  1239. @pytest.mark.slow
  1240. def test_boxplot_subplots_return_type(self):
  1241. df = self.hist_df
  1242. # normal style: return_type=None
  1243. result = df.plot.box(subplots=True)
  1244. assert isinstance(result, Series)
  1245. self._check_box_return_type(result, None, expected_keys=[
  1246. 'height', 'weight', 'category'])
  1247. for t in ['dict', 'axes', 'both']:
  1248. returned = df.plot.box(return_type=t, subplots=True)
  1249. self._check_box_return_type(
  1250. returned, t,
  1251. expected_keys=['height', 'weight', 'category'],
  1252. check_ax_title=False)
  1253. @pytest.mark.slow
  1254. @td.skip_if_no_scipy
  1255. def test_kde_df(self):
  1256. _skip_if_no_scipy_gaussian_kde()
  1257. df = DataFrame(randn(100, 4))
  1258. ax = _check_plot_works(df.plot, kind='kde')
  1259. expected = [pprint_thing(c) for c in df.columns]
  1260. self._check_legend_labels(ax, labels=expected)
  1261. self._check_ticks_props(ax, xrot=0)
  1262. ax = df.plot(kind='kde', rot=20, fontsize=5)
  1263. self._check_ticks_props(ax, xrot=20, xlabelsize=5, ylabelsize=5)
  1264. with tm.assert_produces_warning(UserWarning):
  1265. axes = _check_plot_works(df.plot, kind='kde',
  1266. subplots=True)
  1267. self._check_axes_shape(axes, axes_num=4, layout=(4, 1))
  1268. axes = df.plot(kind='kde', logy=True, subplots=True)
  1269. self._check_ax_scales(axes, yaxis='log')
  1270. @pytest.mark.slow
  1271. @td.skip_if_no_scipy
  1272. def test_kde_missing_vals(self):
  1273. _skip_if_no_scipy_gaussian_kde()
  1274. df = DataFrame(np.random.uniform(size=(100, 4)))
  1275. df.loc[0, 0] = np.nan
  1276. _check_plot_works(df.plot, kind='kde')
  1277. @pytest.mark.slow
  1278. def test_hist_df(self):
  1279. from matplotlib.patches import Rectangle
  1280. df = DataFrame(randn(100, 4))
  1281. series = df[0]
  1282. ax = _check_plot_works(df.plot.hist)
  1283. expected = [pprint_thing(c) for c in df.columns]
  1284. self._check_legend_labels(ax, labels=expected)
  1285. with tm.assert_produces_warning(UserWarning):
  1286. axes = _check_plot_works(df.plot.hist,
  1287. subplots=True, logy=True)
  1288. self._check_axes_shape(axes, axes_num=4, layout=(4, 1))
  1289. self._check_ax_scales(axes, yaxis='log')
  1290. axes = series.plot.hist(rot=40)
  1291. self._check_ticks_props(axes, xrot=40, yrot=0)
  1292. tm.close()
  1293. if plotting._compat._mpl_ge_2_2_0():
  1294. kwargs = {"density": True}
  1295. else:
  1296. kwargs = {"normed": True}
  1297. ax = series.plot.hist(cumulative=True, bins=4, **kwargs)
  1298. # height of last bin (index 5) must be 1.0
  1299. rects = [x for x in ax.get_children() if isinstance(x, Rectangle)]
  1300. tm.assert_almost_equal(rects[-1].get_height(), 1.0)
  1301. tm.close()
  1302. ax = series.plot.hist(cumulative=True, bins=4)
  1303. rects = [x for x in ax.get_children() if isinstance(x, Rectangle)]
  1304. tm.assert_almost_equal(rects[-2].get_height(), 100.0)
  1305. tm.close()
  1306. # if horizontal, yticklabels are rotated
  1307. axes = df.plot.hist(rot=50, fontsize=8, orientation='horizontal')
  1308. self._check_ticks_props(axes, xrot=0, yrot=50, ylabelsize=8)
  1309. def _check_box_coord(self, patches, expected_y=None, expected_h=None,
  1310. expected_x=None, expected_w=None):
  1311. result_y = np.array([p.get_y() for p in patches])
  1312. result_height = np.array([p.get_height() for p in patches])
  1313. result_x = np.array([p.get_x() for p in patches])
  1314. result_width = np.array([p.get_width() for p in patches])
  1315. # dtype is depending on above values, no need to check
  1316. if expected_y is not None:
  1317. tm.assert_numpy_array_equal(result_y, expected_y,
  1318. check_dtype=False)
  1319. if expected_h is not None:
  1320. tm.assert_numpy_array_equal(result_height, expected_h,
  1321. check_dtype=False)
  1322. if expected_x is not None:
  1323. tm.assert_numpy_array_equal(result_x, expected_x,
  1324. check_dtype=False)
  1325. if expected_w is not None:
  1326. tm.assert_numpy_array_equal(result_width, expected_w,
  1327. check_dtype=False)
  1328. @pytest.mark.slow
  1329. def test_hist_df_coord(self):
  1330. normal_df = DataFrame({'A': np.repeat(np.array([1, 2, 3, 4, 5]),
  1331. np.array([10, 9, 8, 7, 6])),
  1332. 'B': np.repeat(np.array([1, 2, 3, 4, 5]),
  1333. np.array([8, 8, 8, 8, 8])),
  1334. 'C': np.repeat(np.array([1, 2, 3, 4, 5]),
  1335. np.array([6, 7, 8, 9, 10]))},
  1336. columns=['A', 'B', 'C'])
  1337. nan_df = DataFrame({'A': np.repeat(np.array([np.nan, 1, 2, 3, 4, 5]),
  1338. np.array([3, 10, 9, 8, 7, 6])),
  1339. 'B': np.repeat(np.array([1, np.nan, 2, 3, 4, 5]),
  1340. np.array([8, 3, 8, 8, 8, 8])),
  1341. 'C': np.repeat(np.array([1, 2, 3, np.nan, 4, 5]),
  1342. np.array([6, 7, 8, 3, 9, 10]))},
  1343. columns=['A', 'B', 'C'])
  1344. for df in [normal_df, nan_df]:
  1345. ax = df.plot.hist(bins=5)
  1346. self._check_box_coord(ax.patches[:5],
  1347. expected_y=np.array([0, 0, 0, 0, 0]),
  1348. expected_h=np.array([10, 9, 8, 7, 6]))
  1349. self._check_box_coord(ax.patches[5:10],
  1350. expected_y=np.array([0, 0, 0, 0, 0]),
  1351. expected_h=np.array([8, 8, 8, 8, 8]))
  1352. self._check_box_coord(ax.patches[10:],
  1353. expected_y=np.array([0, 0, 0, 0, 0]),
  1354. expected_h=np.array([6, 7, 8, 9, 10]))
  1355. ax = df.plot.hist(bins=5, stacked=True)
  1356. self._check_box_coord(ax.patches[:5],
  1357. expected_y=np.array([0, 0, 0, 0, 0]),
  1358. expected_h=np.array([10, 9, 8, 7, 6]))
  1359. self._check_box_coord(ax.patches[5:10],
  1360. expected_y=np.array([10, 9, 8, 7, 6]),
  1361. expected_h=np.array([8, 8, 8, 8, 8]))
  1362. self._check_box_coord(ax.patches[10:],
  1363. expected_y=np.array([18, 17, 16, 15, 14]),
  1364. expected_h=np.array([6, 7, 8, 9, 10]))
  1365. axes = df.plot.hist(bins=5, stacked=True, subplots=True)
  1366. self._check_box_coord(axes[0].patches,
  1367. expected_y=np.array([0, 0, 0, 0, 0]),
  1368. expected_h=np.array([10, 9, 8, 7, 6]))
  1369. self._check_box_coord(axes[1].patches,
  1370. expected_y=np.array([0, 0, 0, 0, 0]),
  1371. expected_h=np.array([8, 8, 8, 8, 8]))
  1372. self._check_box_coord(axes[2].patches,
  1373. expected_y=np.array([0, 0, 0, 0, 0]),
  1374. expected_h=np.array([6, 7, 8, 9, 10]))
  1375. # horizontal
  1376. ax = df.plot.hist(bins=5, orientation='horizontal')
  1377. self._check_box_coord(ax.patches[:5],
  1378. expected_x=np.array([0, 0, 0, 0, 0]),
  1379. expected_w=np.array([10, 9, 8, 7, 6]))
  1380. self._check_box_coord(ax.patches[5:10],
  1381. expected_x=np.array([0, 0, 0, 0, 0]),
  1382. expected_w=np.array([8, 8, 8, 8, 8]))
  1383. self._check_box_coord(ax.patches[10:],
  1384. expected_x=np.array([0, 0, 0, 0, 0]),
  1385. expected_w=np.array([6, 7, 8, 9, 10]))
  1386. ax = df.plot.hist(bins=5, stacked=True,
  1387. orientation='horizontal')
  1388. self._check_box_coord(ax.patches[:5],
  1389. expected_x=np.array([0, 0, 0, 0, 0]),
  1390. expected_w=np.array([10, 9, 8, 7, 6]))
  1391. self._check_box_coord(ax.patches[5:10],
  1392. expected_x=np.array([10, 9, 8, 7, 6]),
  1393. expected_w=np.array([8, 8, 8, 8, 8]))
  1394. self._check_box_coord(
  1395. ax.patches[10:],
  1396. expected_x=np.array([18, 17, 16, 15, 14]),
  1397. expected_w=np.array([6, 7, 8, 9, 10]))
  1398. axes = df.plot.hist(bins=5, stacked=True, subplots=True,
  1399. orientation='horizontal')
  1400. self._check_box_coord(axes[0].patches,
  1401. expected_x=np.array([0, 0, 0, 0, 0]),
  1402. expected_w=np.array([10, 9, 8, 7, 6]))
  1403. self._check_box_coord(axes[1].patches,
  1404. expected_x=np.array([0, 0, 0, 0, 0]),
  1405. expected_w=np.array([8, 8, 8, 8, 8]))
  1406. self._check_box_coord(axes[2].patches,
  1407. expected_x=np.array([0, 0, 0, 0, 0]),
  1408. expected_w=np.array([6, 7, 8, 9, 10]))
  1409. @pytest.mark.slow
  1410. def test_plot_int_columns(self):
  1411. df = DataFrame(randn(100, 4)).cumsum()
  1412. _check_plot_works(df.plot, legend=True)
  1413. @pytest.mark.slow
  1414. def test_df_legend_labels(self):
  1415. kinds = ['line', 'bar', 'barh', 'kde', 'area', 'hist']
  1416. df = DataFrame(rand(3, 3), columns=['a', 'b', 'c'])
  1417. df2 = DataFrame(rand(3, 3), columns=['d', 'e', 'f'])
  1418. df3 = DataFrame(rand(3, 3), columns=['g', 'h', 'i'])
  1419. df4 = DataFrame(rand(3, 3), columns=['j', 'k', 'l'])
  1420. for kind in kinds:
  1421. if not _ok_for_gaussian_kde(kind):
  1422. continue
  1423. ax = df.plot(kind=kind, legend=True)
  1424. self._check_legend_labels(ax, labels=df.columns)
  1425. ax = df2.plot(kind=kind, legend=False, ax=ax)
  1426. self._check_legend_labels(ax, labels=df.columns)
  1427. ax = df3.plot(kind=kind, legend=True, ax=ax)
  1428. self._check_legend_labels(ax, labels=df.columns.union(df3.columns))
  1429. ax = df4.plot(kind=kind, legend='reverse', ax=ax)
  1430. expected = list(df.columns.union(df3.columns)) + list(reversed(
  1431. df4.columns))
  1432. self._check_legend_labels(ax, labels=expected)
  1433. # Secondary Y
  1434. ax = df.plot(legend=True, secondary_y='b')
  1435. self._check_legend_labels(ax, labels=['a', 'b (right)', 'c'])
  1436. ax = df2.plot(legend=False, ax=ax)
  1437. self._check_legend_labels(ax, labels=['a', 'b (right)', 'c'])
  1438. ax = df3.plot(kind='bar', legend=True, secondary_y='h', ax=ax)
  1439. self._check_legend_labels(
  1440. ax, labels=['a', 'b (right)', 'c', 'g', 'h (right)', 'i'])
  1441. # Time Series
  1442. ind = date_range('1/1/2014', periods=3)
  1443. df = DataFrame(randn(3, 3), columns=['a', 'b', 'c'], index=ind)
  1444. df2 = DataFrame(randn(3, 3), columns=['d', 'e', 'f'], index=ind)
  1445. df3 = DataFrame(randn(3, 3), columns=['g', 'h', 'i'], index=ind)
  1446. ax = df.plot(legend=True, secondary_y='b')
  1447. self._check_legend_labels(ax, labels=['a', 'b (right)', 'c'])
  1448. ax = df2.plot(legend=False, ax=ax)
  1449. self._check_legend_labels(ax, labels=['a', 'b (right)', 'c'])
  1450. ax = df3.plot(legend=True, ax=ax)
  1451. self._check_legend_labels(
  1452. ax, labels=['a', 'b (right)', 'c', 'g', 'h', 'i'])
  1453. # scatter
  1454. ax = df.plot.scatter(x='a', y='b', label='data1')
  1455. self._check_legend_labels(ax, labels=['data1'])
  1456. ax = df2.plot.scatter(x='d', y='e', legend=False, label='data2', ax=ax)
  1457. self._check_legend_labels(ax, labels=['data1'])
  1458. ax = df3.plot.scatter(x='g', y='h', label='data3', ax=ax)
  1459. self._check_legend_labels(ax, labels=['data1', 'data3'])
  1460. # ensure label args pass through and
  1461. # index name does not mutate
  1462. # column names don't mutate
  1463. df5 = df.set_index('a')
  1464. ax = df5.plot(y='b')
  1465. self._check_legend_labels(ax, labels=['b'])
  1466. ax = df5.plot(y='b', label='LABEL_b')
  1467. self._check_legend_labels(ax, labels=['LABEL_b'])
  1468. self._check_text_labels(ax.xaxis.get_label(), 'a')
  1469. ax = df5.plot(y='c', label='LABEL_c', ax=ax)
  1470. self._check_legend_labels(ax, labels=['LABEL_b', 'LABEL_c'])
  1471. assert df5.columns.tolist() == ['b', 'c']
  1472. def test_legend_name(self):
  1473. multi = DataFrame(randn(4, 4),
  1474. columns=[np.array(['a', 'a', 'b', 'b']),
  1475. np.array(['x', 'y', 'x', 'y'])])
  1476. multi.columns.names = ['group', 'individual']
  1477. ax = multi.plot()
  1478. leg_title = ax.legend_.get_title()
  1479. self._check_text_labels(leg_title, 'group,individual')
  1480. df = DataFrame(randn(5, 5))
  1481. ax = df.plot(legend=True, ax=ax)
  1482. leg_title = ax.legend_.get_title()
  1483. self._check_text_labels(leg_title, 'group,individual')
  1484. df.columns.name = 'new'
  1485. ax = df.plot(legend=False, ax=ax)
  1486. leg_title = ax.legend_.get_title()
  1487. self._check_text_labels(leg_title, 'group,individual')
  1488. ax = df.plot(legend=True, ax=ax)
  1489. leg_title = ax.legend_.get_title()
  1490. self._check_text_labels(leg_title, 'new')
  1491. @pytest.mark.slow
  1492. def test_no_legend(self):
  1493. kinds = ['line', 'bar', 'barh', 'kde', 'area', 'hist']
  1494. df = DataFrame(rand(3, 3), columns=['a', 'b', 'c'])
  1495. for kind in kinds:
  1496. if not _ok_for_gaussian_kde(kind):
  1497. continue
  1498. ax = df.plot(kind=kind, legend=False)
  1499. self._check_legend_labels(ax, visible=False)
  1500. @pytest.mark.slow
  1501. def test_style_by_column(self):
  1502. import matplotlib.pyplot as plt
  1503. fig = plt.gcf()
  1504. df = DataFrame(randn(100, 3))
  1505. for markers in [{0: '^',
  1506. 1: '+',
  1507. 2: 'o'}, {0: '^',
  1508. 1: '+'}, ['^', '+', 'o'], ['^', '+']]:
  1509. fig.clf()
  1510. fig.add_subplot(111)
  1511. ax = df.plot(style=markers)
  1512. for i, l in enumerate(ax.get_lines()[:len(markers)]):
  1513. assert l.get_marker() == markers[i]
  1514. @pytest.mark.slow
  1515. def test_line_label_none(self):
  1516. s = Series([1, 2])
  1517. ax = s.plot()
  1518. assert ax.get_legend() is None
  1519. ax = s.plot(legend=True)
  1520. assert ax.get_legend().get_texts()[0].get_text() == 'None'
  1521. @pytest.mark.slow
  1522. def test_line_colors(self):
  1523. from matplotlib import cm
  1524. custom_colors = 'rgcby'
  1525. df = DataFrame(randn(5, 5))
  1526. ax = df.plot(color=custom_colors)
  1527. self._check_colors(ax.get_lines(), linecolors=custom_colors)
  1528. tm.close()
  1529. ax2 = df.plot(color=custom_colors)
  1530. lines2 = ax2.get_lines()
  1531. for l1, l2 in zip(ax.get_lines(), lines2):
  1532. assert l1.get_color() == l2.get_color()
  1533. tm.close()
  1534. ax = df.plot(colormap='jet')
  1535. rgba_colors = lmap(cm.jet, np.linspace(0, 1, len(df)))
  1536. self._check_colors(ax.get_lines(), linecolors=rgba_colors)
  1537. tm.close()
  1538. ax = df.plot(colormap=cm.jet)
  1539. rgba_colors = lmap(cm.jet, np.linspace(0, 1, len(df)))
  1540. self._check_colors(ax.get_lines(), linecolors=rgba_colors)
  1541. tm.close()
  1542. # make color a list if plotting one column frame
  1543. # handles cases like df.plot(color='DodgerBlue')
  1544. ax = df.loc[:, [0]].plot(color='DodgerBlue')
  1545. self._check_colors(ax.lines, linecolors=['DodgerBlue'])
  1546. ax = df.plot(color='red')
  1547. self._check_colors(ax.get_lines(), linecolors=['red'] * 5)
  1548. tm.close()
  1549. # GH 10299
  1550. custom_colors = ['#FF0000', '#0000FF', '#FFFF00', '#000000', '#FFFFFF']
  1551. ax = df.plot(color=custom_colors)
  1552. self._check_colors(ax.get_lines(), linecolors=custom_colors)
  1553. tm.close()
  1554. with pytest.raises(ValueError):
  1555. # Color contains shorthand hex value results in ValueError
  1556. custom_colors = ['#F00', '#00F', '#FF0', '#000', '#FFF']
  1557. # Forced show plot
  1558. _check_plot_works(df.plot, color=custom_colors)
  1559. @pytest.mark.slow
  1560. def test_dont_modify_colors(self):
  1561. colors = ['r', 'g', 'b']
  1562. pd.DataFrame(np.random.rand(10, 2)).plot(color=colors)
  1563. assert len(colors) == 3
  1564. @pytest.mark.slow
  1565. def test_line_colors_and_styles_subplots(self):
  1566. # GH 9894
  1567. from matplotlib import cm
  1568. default_colors = self._unpack_cycler(self.plt.rcParams)
  1569. df = DataFrame(randn(5, 5))
  1570. axes = df.plot(subplots=True)
  1571. for ax, c in zip(axes, list(default_colors)):
  1572. c = [c]
  1573. self._check_colors(ax.get_lines(), linecolors=c)
  1574. tm.close()
  1575. # single color char
  1576. axes = df.plot(subplots=True, color='k')
  1577. for ax in axes:
  1578. self._check_colors(ax.get_lines(), linecolors=['k'])
  1579. tm.close()
  1580. # single color str
  1581. axes = df.plot(subplots=True, color='green')
  1582. for ax in axes:
  1583. self._check_colors(ax.get_lines(), linecolors=['green'])
  1584. tm.close()
  1585. custom_colors = 'rgcby'
  1586. axes = df.plot(color=custom_colors, subplots=True)
  1587. for ax, c in zip(axes, list(custom_colors)):
  1588. self._check_colors(ax.get_lines(), linecolors=[c])
  1589. tm.close()
  1590. axes = df.plot(color=list(custom_colors), subplots=True)
  1591. for ax, c in zip(axes, list(custom_colors)):
  1592. self._check_colors(ax.get_lines(), linecolors=[c])
  1593. tm.close()
  1594. # GH 10299
  1595. custom_colors = ['#FF0000', '#0000FF', '#FFFF00', '#000000', '#FFFFFF']
  1596. axes = df.plot(color=custom_colors, subplots=True)
  1597. for ax, c in zip(axes, list(custom_colors)):
  1598. self._check_colors(ax.get_lines(), linecolors=[c])
  1599. tm.close()
  1600. with pytest.raises(ValueError):
  1601. # Color contains shorthand hex value results in ValueError
  1602. custom_colors = ['#F00', '#00F', '#FF0', '#000', '#FFF']
  1603. # Forced show plot
  1604. # _check_plot_works adds an ax so catch warning. see GH #13188
  1605. with tm.assert_produces_warning(UserWarning):
  1606. _check_plot_works(df.plot, color=custom_colors, subplots=True)
  1607. rgba_colors = lmap(cm.jet, np.linspace(0, 1, len(df)))
  1608. for cmap in ['jet', cm.jet]:
  1609. axes = df.plot(colormap=cmap, subplots=True)
  1610. for ax, c in zip(axes, rgba_colors):
  1611. self._check_colors(ax.get_lines(), linecolors=[c])
  1612. tm.close()
  1613. # make color a list if plotting one column frame
  1614. # handles cases like df.plot(color='DodgerBlue')
  1615. axes = df.loc[:, [0]].plot(color='DodgerBlue', subplots=True)
  1616. self._check_colors(axes[0].lines, linecolors=['DodgerBlue'])
  1617. # single character style
  1618. axes = df.plot(style='r', subplots=True)
  1619. for ax in axes:
  1620. self._check_colors(ax.get_lines(), linecolors=['r'])
  1621. tm.close()
  1622. # list of styles
  1623. styles = list('rgcby')
  1624. axes = df.plot(style=styles, subplots=True)
  1625. for ax, c in zip(axes, styles):
  1626. self._check_colors(ax.get_lines(), linecolors=[c])
  1627. tm.close()
  1628. @pytest.mark.slow
  1629. def test_area_colors(self):
  1630. from matplotlib import cm
  1631. from matplotlib.collections import PolyCollection
  1632. custom_colors = 'rgcby'
  1633. df = DataFrame(rand(5, 5))
  1634. ax = df.plot.area(color=custom_colors)
  1635. self._check_colors(ax.get_lines(), linecolors=custom_colors)
  1636. poly = [o for o in ax.get_children() if isinstance(o, PolyCollection)]
  1637. self._check_colors(poly, facecolors=custom_colors)
  1638. handles, labels = ax.get_legend_handles_labels()
  1639. self._check_colors(handles, facecolors=custom_colors)
  1640. for h in handles:
  1641. assert h.get_alpha() is None
  1642. tm.close()
  1643. ax = df.plot.area(colormap='jet')
  1644. jet_colors = lmap(cm.jet, np.linspace(0, 1, len(df)))
  1645. self._check_colors(ax.get_lines(), linecolors=jet_colors)
  1646. poly = [o for o in ax.get_children() if isinstance(o, PolyCollection)]
  1647. self._check_colors(poly, facecolors=jet_colors)
  1648. handles, labels = ax.get_legend_handles_labels()
  1649. self._check_colors(handles, facecolors=jet_colors)
  1650. for h in handles:
  1651. assert h.get_alpha() is None
  1652. tm.close()
  1653. # When stacked=False, alpha is set to 0.5
  1654. ax = df.plot.area(colormap=cm.jet, stacked=False)
  1655. self._check_colors(ax.get_lines(), linecolors=jet_colors)
  1656. poly = [o for o in ax.get_children() if isinstance(o, PolyCollection)]
  1657. jet_with_alpha = [(c[0], c[1], c[2], 0.5) for c in jet_colors]
  1658. self._check_colors(poly, facecolors=jet_with_alpha)
  1659. handles, labels = ax.get_legend_handles_labels()
  1660. linecolors = jet_with_alpha
  1661. self._check_colors(handles[:len(jet_colors)], linecolors=linecolors)
  1662. for h in handles:
  1663. assert h.get_alpha() == 0.5
  1664. @pytest.mark.slow
  1665. def test_hist_colors(self):
  1666. default_colors = self._unpack_cycler(self.plt.rcParams)
  1667. df = DataFrame(randn(5, 5))
  1668. ax = df.plot.hist()
  1669. self._check_colors(ax.patches[::10], facecolors=default_colors[:5])
  1670. tm.close()
  1671. custom_colors = 'rgcby'
  1672. ax = df.plot.hist(color=custom_colors)
  1673. self._check_colors(ax.patches[::10], facecolors=custom_colors)
  1674. tm.close()
  1675. from matplotlib import cm
  1676. # Test str -> colormap functionality
  1677. ax = df.plot.hist(colormap='jet')
  1678. rgba_colors = lmap(cm.jet, np.linspace(0, 1, 5))
  1679. self._check_colors(ax.patches[::10], facecolors=rgba_colors)
  1680. tm.close()
  1681. # Test colormap functionality
  1682. ax = df.plot.hist(colormap=cm.jet)
  1683. rgba_colors = lmap(cm.jet, np.linspace(0, 1, 5))
  1684. self._check_colors(ax.patches[::10], facecolors=rgba_colors)
  1685. tm.close()
  1686. ax = df.loc[:, [0]].plot.hist(color='DodgerBlue')
  1687. self._check_colors([ax.patches[0]], facecolors=['DodgerBlue'])
  1688. ax = df.plot(kind='hist', color='green')
  1689. self._check_colors(ax.patches[::10], facecolors=['green'] * 5)
  1690. tm.close()
  1691. @pytest.mark.slow
  1692. @td.skip_if_no_scipy
  1693. def test_kde_colors(self):
  1694. _skip_if_no_scipy_gaussian_kde()
  1695. from matplotlib import cm
  1696. custom_colors = 'rgcby'
  1697. df = DataFrame(rand(5, 5))
  1698. ax = df.plot.kde(color=custom_colors)
  1699. self._check_colors(ax.get_lines(), linecolors=custom_colors)
  1700. tm.close()
  1701. ax = df.plot.kde(colormap='jet')
  1702. rgba_colors = lmap(cm.jet, np.linspace(0, 1, len(df)))
  1703. self._check_colors(ax.get_lines(), linecolors=rgba_colors)
  1704. tm.close()
  1705. ax = df.plot.kde(colormap=cm.jet)
  1706. rgba_colors = lmap(cm.jet, np.linspace(0, 1, len(df)))
  1707. self._check_colors(ax.get_lines(), linecolors=rgba_colors)
  1708. @pytest.mark.slow
  1709. @td.skip_if_no_scipy
  1710. def test_kde_colors_and_styles_subplots(self):
  1711. _skip_if_no_scipy_gaussian_kde()
  1712. from matplotlib import cm
  1713. default_colors = self._unpack_cycler(self.plt.rcParams)
  1714. df = DataFrame(randn(5, 5))
  1715. axes = df.plot(kind='kde', subplots=True)
  1716. for ax, c in zip(axes, list(default_colors)):
  1717. self._check_colors(ax.get_lines(), linecolors=[c])
  1718. tm.close()
  1719. # single color char
  1720. axes = df.plot(kind='kde', color='k', subplots=True)
  1721. for ax in axes:
  1722. self._check_colors(ax.get_lines(), linecolors=['k'])
  1723. tm.close()
  1724. # single color str
  1725. axes = df.plot(kind='kde', color='red', subplots=True)
  1726. for ax in axes:
  1727. self._check_colors(ax.get_lines(), linecolors=['red'])
  1728. tm.close()
  1729. custom_colors = 'rgcby'
  1730. axes = df.plot(kind='kde', color=custom_colors, subplots=True)
  1731. for ax, c in zip(axes, list(custom_colors)):
  1732. self._check_colors(ax.get_lines(), linecolors=[c])
  1733. tm.close()
  1734. rgba_colors = lmap(cm.jet, np.linspace(0, 1, len(df)))
  1735. for cmap in ['jet', cm.jet]:
  1736. axes = df.plot(kind='kde', colormap=cmap, subplots=True)
  1737. for ax, c in zip(axes, rgba_colors):
  1738. self._check_colors(ax.get_lines(), linecolors=[c])
  1739. tm.close()
  1740. # make color a list if plotting one column frame
  1741. # handles cases like df.plot(color='DodgerBlue')
  1742. axes = df.loc[:, [0]].plot(kind='kde', color='DodgerBlue',
  1743. subplots=True)
  1744. self._check_colors(axes[0].lines, linecolors=['DodgerBlue'])
  1745. # single character style
  1746. axes = df.plot(kind='kde', style='r', subplots=True)
  1747. for ax in axes:
  1748. self._check_colors(ax.get_lines(), linecolors=['r'])
  1749. tm.close()
  1750. # list of styles
  1751. styles = list('rgcby')
  1752. axes = df.plot(kind='kde', style=styles, subplots=True)
  1753. for ax, c in zip(axes, styles):
  1754. self._check_colors(ax.get_lines(), linecolors=[c])
  1755. tm.close()
  1756. @pytest.mark.slow
  1757. def test_boxplot_colors(self):
  1758. def _check_colors(bp, box_c, whiskers_c, medians_c, caps_c='k',
  1759. fliers_c=None):
  1760. # TODO: outside this func?
  1761. if fliers_c is None:
  1762. fliers_c = 'k'
  1763. self._check_colors(bp['boxes'],
  1764. linecolors=[box_c] * len(bp['boxes']))
  1765. self._check_colors(bp['whiskers'],
  1766. linecolors=[whiskers_c] * len(bp['whiskers']))
  1767. self._check_colors(bp['medians'],
  1768. linecolors=[medians_c] * len(bp['medians']))
  1769. self._check_colors(bp['fliers'],
  1770. linecolors=[fliers_c] * len(bp['fliers']))
  1771. self._check_colors(bp['caps'],
  1772. linecolors=[caps_c] * len(bp['caps']))
  1773. default_colors = self._unpack_cycler(self.plt.rcParams)
  1774. df = DataFrame(randn(5, 5))
  1775. bp = df.plot.box(return_type='dict')
  1776. _check_colors(bp, default_colors[0], default_colors[0],
  1777. default_colors[2])
  1778. tm.close()
  1779. dict_colors = dict(boxes='#572923', whiskers='#982042',
  1780. medians='#804823', caps='#123456')
  1781. bp = df.plot.box(color=dict_colors, sym='r+', return_type='dict')
  1782. _check_colors(bp, dict_colors['boxes'], dict_colors['whiskers'],
  1783. dict_colors['medians'], dict_colors['caps'], 'r')
  1784. tm.close()
  1785. # partial colors
  1786. dict_colors = dict(whiskers='c', medians='m')
  1787. bp = df.plot.box(color=dict_colors, return_type='dict')
  1788. _check_colors(bp, default_colors[0], 'c', 'm')
  1789. tm.close()
  1790. from matplotlib import cm
  1791. # Test str -> colormap functionality
  1792. bp = df.plot.box(colormap='jet', return_type='dict')
  1793. jet_colors = lmap(cm.jet, np.linspace(0, 1, 3))
  1794. _check_colors(bp, jet_colors[0], jet_colors[0], jet_colors[2])
  1795. tm.close()
  1796. # Test colormap functionality
  1797. bp = df.plot.box(colormap=cm.jet, return_type='dict')
  1798. _check_colors(bp, jet_colors[0], jet_colors[0], jet_colors[2])
  1799. tm.close()
  1800. # string color is applied to all artists except fliers
  1801. bp = df.plot.box(color='DodgerBlue', return_type='dict')
  1802. _check_colors(bp, 'DodgerBlue', 'DodgerBlue', 'DodgerBlue',
  1803. 'DodgerBlue')
  1804. # tuple is also applied to all artists except fliers
  1805. bp = df.plot.box(color=(0, 1, 0), sym='#123456', return_type='dict')
  1806. _check_colors(bp, (0, 1, 0), (0, 1, 0), (0, 1, 0),
  1807. (0, 1, 0), '#123456')
  1808. with pytest.raises(ValueError):
  1809. # Color contains invalid key results in ValueError
  1810. df.plot.box(color=dict(boxes='red', xxxx='blue'))
  1811. def test_default_color_cycle(self):
  1812. import matplotlib.pyplot as plt
  1813. import cycler
  1814. colors = list('rgbk')
  1815. plt.rcParams['axes.prop_cycle'] = cycler.cycler('color', colors)
  1816. df = DataFrame(randn(5, 3))
  1817. ax = df.plot()
  1818. expected = self._unpack_cycler(plt.rcParams)[:3]
  1819. self._check_colors(ax.get_lines(), linecolors=expected)
  1820. def test_unordered_ts(self):
  1821. df = DataFrame(np.array([3.0, 2.0, 1.0]),
  1822. index=[date(2012, 10, 1),
  1823. date(2012, 9, 1),
  1824. date(2012, 8, 1)],
  1825. columns=['test'])
  1826. ax = df.plot()
  1827. xticks = ax.lines[0].get_xdata()
  1828. assert xticks[0] < xticks[1]
  1829. ydata = ax.lines[0].get_ydata()
  1830. tm.assert_numpy_array_equal(ydata, np.array([1.0, 2.0, 3.0]))
  1831. def test_kind_both_ways(self):
  1832. df = DataFrame({'x': [1, 2, 3]})
  1833. for kind in plotting._core._common_kinds:
  1834. if not _ok_for_gaussian_kde(kind):
  1835. continue
  1836. df.plot(kind=kind)
  1837. getattr(df.plot, kind)()
  1838. for kind in ['scatter', 'hexbin']:
  1839. df.plot('x', 'x', kind=kind)
  1840. getattr(df.plot, kind)('x', 'x')
  1841. def test_all_invalid_plot_data(self):
  1842. df = DataFrame(list('abcd'))
  1843. for kind in plotting._core._common_kinds:
  1844. if not _ok_for_gaussian_kde(kind):
  1845. continue
  1846. with pytest.raises(TypeError):
  1847. df.plot(kind=kind)
  1848. @pytest.mark.slow
  1849. def test_partially_invalid_plot_data(self):
  1850. with tm.RNGContext(42):
  1851. df = DataFrame(randn(10, 2), dtype=object)
  1852. df[np.random.rand(df.shape[0]) > 0.5] = 'a'
  1853. for kind in plotting._core._common_kinds:
  1854. if not _ok_for_gaussian_kde(kind):
  1855. continue
  1856. with pytest.raises(TypeError):
  1857. df.plot(kind=kind)
  1858. with tm.RNGContext(42):
  1859. # area plot doesn't support positive/negative mixed data
  1860. kinds = ['area']
  1861. df = DataFrame(rand(10, 2), dtype=object)
  1862. df[np.random.rand(df.shape[0]) > 0.5] = 'a'
  1863. for kind in kinds:
  1864. with pytest.raises(TypeError):
  1865. df.plot(kind=kind)
  1866. def test_invalid_kind(self):
  1867. df = DataFrame(randn(10, 2))
  1868. with pytest.raises(ValueError):
  1869. df.plot(kind='aasdf')
  1870. @pytest.mark.parametrize("x,y,lbl", [
  1871. (['B', 'C'], 'A', 'a'),
  1872. (['A'], ['B', 'C'], ['b', 'c']),
  1873. ('A', ['B', 'C'], 'badlabel')
  1874. ])
  1875. def test_invalid_xy_args(self, x, y, lbl):
  1876. # GH 18671, 19699 allows y to be list-like but not x
  1877. df = DataFrame({"A": [1, 2], 'B': [3, 4], 'C': [5, 6]})
  1878. with pytest.raises(ValueError):
  1879. df.plot(x=x, y=y, label=lbl)
  1880. @pytest.mark.parametrize("x,y", [
  1881. ('A', 'B'),
  1882. (['A'], 'B')
  1883. ])
  1884. def test_invalid_xy_args_dup_cols(self, x, y):
  1885. # GH 18671, 19699 allows y to be list-like but not x
  1886. df = DataFrame([[1, 3, 5], [2, 4, 6]], columns=list('AAB'))
  1887. with pytest.raises(ValueError):
  1888. df.plot(x=x, y=y)
  1889. @pytest.mark.parametrize("x,y,lbl,colors", [
  1890. ('A', ['B'], ['b'], ['red']),
  1891. ('A', ['B', 'C'], ['b', 'c'], ['red', 'blue']),
  1892. (0, [1, 2], ['bokeh', 'cython'], ['green', 'yellow'])
  1893. ])
  1894. def test_y_listlike(self, x, y, lbl, colors):
  1895. # GH 19699: tests list-like y and verifies lbls & colors
  1896. df = DataFrame({"A": [1, 2], 'B': [3, 4], 'C': [5, 6]})
  1897. _check_plot_works(df.plot, x='A', y=y, label=lbl)
  1898. ax = df.plot(x=x, y=y, label=lbl, color=colors)
  1899. assert len(ax.lines) == len(y)
  1900. self._check_colors(ax.get_lines(), linecolors=colors)
  1901. @pytest.mark.parametrize("x,y,colnames", [
  1902. (0, 1, ['A', 'B']),
  1903. (1, 0, [0, 1])
  1904. ])
  1905. def test_xy_args_integer(self, x, y, colnames):
  1906. # GH 20056: tests integer args for xy and checks col names
  1907. df = DataFrame({"A": [1, 2], 'B': [3, 4]})
  1908. df.columns = colnames
  1909. _check_plot_works(df.plot, x=x, y=y)
  1910. @pytest.mark.slow
  1911. def test_hexbin_basic(self):
  1912. df = self.hexbin_df
  1913. ax = df.plot.hexbin(x='A', y='B', gridsize=10)
  1914. # TODO: need better way to test. This just does existence.
  1915. assert len(ax.collections) == 1
  1916. # GH 6951
  1917. axes = df.plot.hexbin(x='A', y='B', subplots=True)
  1918. # hexbin should have 2 axes in the figure, 1 for plotting and another
  1919. # is colorbar
  1920. assert len(axes[0].figure.axes) == 2
  1921. # return value is single axes
  1922. self._check_axes_shape(axes, axes_num=1, layout=(1, 1))
  1923. @pytest.mark.slow
  1924. def test_hexbin_with_c(self):
  1925. df = self.hexbin_df
  1926. ax = df.plot.hexbin(x='A', y='B', C='C')
  1927. assert len(ax.collections) == 1
  1928. ax = df.plot.hexbin(x='A', y='B', C='C', reduce_C_function=np.std)
  1929. assert len(ax.collections) == 1
  1930. @pytest.mark.slow
  1931. def test_hexbin_cmap(self):
  1932. df = self.hexbin_df
  1933. # Default to BuGn
  1934. ax = df.plot.hexbin(x='A', y='B')
  1935. assert ax.collections[0].cmap.name == 'BuGn'
  1936. cm = 'cubehelix'
  1937. ax = df.plot.hexbin(x='A', y='B', colormap=cm)
  1938. assert ax.collections[0].cmap.name == cm
  1939. @pytest.mark.slow
  1940. def test_no_color_bar(self):
  1941. df = self.hexbin_df
  1942. ax = df.plot.hexbin(x='A', y='B', colorbar=None)
  1943. assert ax.collections[0].colorbar is None
  1944. @pytest.mark.slow
  1945. def test_allow_cmap(self):
  1946. df = self.hexbin_df
  1947. ax = df.plot.hexbin(x='A', y='B', cmap='YlGn')
  1948. assert ax.collections[0].cmap.name == 'YlGn'
  1949. with pytest.raises(TypeError):
  1950. df.plot.hexbin(x='A', y='B', cmap='YlGn', colormap='BuGn')
  1951. @pytest.mark.slow
  1952. def test_pie_df(self):
  1953. df = DataFrame(np.random.rand(5, 3), columns=['X', 'Y', 'Z'],
  1954. index=['a', 'b', 'c', 'd', 'e'])
  1955. with pytest.raises(ValueError):
  1956. df.plot.pie()
  1957. ax = _check_plot_works(df.plot.pie, y='Y')
  1958. self._check_text_labels(ax.texts, df.index)
  1959. ax = _check_plot_works(df.plot.pie, y=2)
  1960. self._check_text_labels(ax.texts, df.index)
  1961. # _check_plot_works adds an ax so catch warning. see GH #13188
  1962. with tm.assert_produces_warning(UserWarning):
  1963. axes = _check_plot_works(df.plot.pie,
  1964. subplots=True)
  1965. assert len(axes) == len(df.columns)
  1966. for ax in axes:
  1967. self._check_text_labels(ax.texts, df.index)
  1968. for ax, ylabel in zip(axes, df.columns):
  1969. assert ax.get_ylabel() == ylabel
  1970. labels = ['A', 'B', 'C', 'D', 'E']
  1971. color_args = ['r', 'g', 'b', 'c', 'm']
  1972. with tm.assert_produces_warning(UserWarning):
  1973. axes = _check_plot_works(df.plot.pie,
  1974. subplots=True, labels=labels,
  1975. colors=color_args)
  1976. assert len(axes) == len(df.columns)
  1977. for ax in axes:
  1978. self._check_text_labels(ax.texts, labels)
  1979. self._check_colors(ax.patches, facecolors=color_args)
  1980. def test_pie_df_nan(self):
  1981. df = DataFrame(np.random.rand(4, 4))
  1982. for i in range(4):
  1983. df.iloc[i, i] = np.nan
  1984. fig, axes = self.plt.subplots(ncols=4)
  1985. df.plot.pie(subplots=True, ax=axes, legend=True)
  1986. base_expected = ['0', '1', '2', '3']
  1987. for i, ax in enumerate(axes):
  1988. expected = list(base_expected) # force copy
  1989. expected[i] = ''
  1990. result = [x.get_text() for x in ax.texts]
  1991. assert result == expected
  1992. # legend labels
  1993. # NaN's not included in legend with subplots
  1994. # see https://github.com/pandas-dev/pandas/issues/8390
  1995. assert ([x.get_text() for x in ax.get_legend().get_texts()] ==
  1996. base_expected[:i] + base_expected[i + 1:])
  1997. @pytest.mark.slow
  1998. def test_errorbar_plot(self):
  1999. with warnings.catch_warnings():
  2000. d = {'x': np.arange(12), 'y': np.arange(12, 0, -1)}
  2001. df = DataFrame(d)
  2002. d_err = {'x': np.ones(12) * 0.2, 'y': np.ones(12) * 0.4}
  2003. df_err = DataFrame(d_err)
  2004. # check line plots
  2005. ax = _check_plot_works(df.plot, yerr=df_err, logy=True)
  2006. self._check_has_errorbars(ax, xerr=0, yerr=2)
  2007. ax = _check_plot_works(df.plot, yerr=df_err, logx=True, logy=True)
  2008. self._check_has_errorbars(ax, xerr=0, yerr=2)
  2009. ax = _check_plot_works(df.plot, yerr=df_err, loglog=True)
  2010. self._check_has_errorbars(ax, xerr=0, yerr=2)
  2011. kinds = ['line', 'bar', 'barh']
  2012. for kind in kinds:
  2013. ax = _check_plot_works(df.plot, yerr=df_err['x'], kind=kind)
  2014. self._check_has_errorbars(ax, xerr=0, yerr=2)
  2015. ax = _check_plot_works(df.plot, yerr=d_err, kind=kind)
  2016. self._check_has_errorbars(ax, xerr=0, yerr=2)
  2017. ax = _check_plot_works(df.plot, yerr=df_err, xerr=df_err,
  2018. kind=kind)
  2019. self._check_has_errorbars(ax, xerr=2, yerr=2)
  2020. ax = _check_plot_works(df.plot, yerr=df_err['x'],
  2021. xerr=df_err['x'],
  2022. kind=kind)
  2023. self._check_has_errorbars(ax, xerr=2, yerr=2)
  2024. ax = _check_plot_works(df.plot, xerr=0.2, yerr=0.2, kind=kind)
  2025. self._check_has_errorbars(ax, xerr=2, yerr=2)
  2026. # _check_plot_works adds an ax so catch warning. see GH #13188
  2027. axes = _check_plot_works(df.plot,
  2028. yerr=df_err, xerr=df_err,
  2029. subplots=True,
  2030. kind=kind)
  2031. self._check_has_errorbars(axes, xerr=1, yerr=1)
  2032. ax = _check_plot_works((df + 1).plot, yerr=df_err,
  2033. xerr=df_err, kind='bar', log=True)
  2034. self._check_has_errorbars(ax, xerr=2, yerr=2)
  2035. # yerr is raw error values
  2036. ax = _check_plot_works(df['y'].plot, yerr=np.ones(12) * 0.4)
  2037. self._check_has_errorbars(ax, xerr=0, yerr=1)
  2038. ax = _check_plot_works(df.plot, yerr=np.ones((2, 12)) * 0.4)
  2039. self._check_has_errorbars(ax, xerr=0, yerr=2)
  2040. # yerr is iterator
  2041. import itertools
  2042. ax = _check_plot_works(df.plot,
  2043. yerr=itertools.repeat(0.1, len(df)))
  2044. self._check_has_errorbars(ax, xerr=0, yerr=2)
  2045. # yerr is column name
  2046. for yerr in ['yerr', u('誤差')]:
  2047. s_df = df.copy()
  2048. s_df[yerr] = np.ones(12) * 0.2
  2049. ax = _check_plot_works(s_df.plot, yerr=yerr)
  2050. self._check_has_errorbars(ax, xerr=0, yerr=2)
  2051. ax = _check_plot_works(s_df.plot, y='y', x='x', yerr=yerr)
  2052. self._check_has_errorbars(ax, xerr=0, yerr=1)
  2053. with pytest.raises(ValueError):
  2054. df.plot(yerr=np.random.randn(11))
  2055. df_err = DataFrame({'x': ['zzz'] * 12, 'y': ['zzz'] * 12})
  2056. with pytest.raises((ValueError, TypeError)):
  2057. df.plot(yerr=df_err)
  2058. @pytest.mark.slow
  2059. def test_errorbar_with_integer_column_names(self):
  2060. # test with integer column names
  2061. df = DataFrame(np.random.randn(10, 2))
  2062. df_err = DataFrame(np.random.randn(10, 2))
  2063. ax = _check_plot_works(df.plot, yerr=df_err)
  2064. self._check_has_errorbars(ax, xerr=0, yerr=2)
  2065. ax = _check_plot_works(df.plot, y=0, yerr=1)
  2066. self._check_has_errorbars(ax, xerr=0, yerr=1)
  2067. @pytest.mark.slow
  2068. def test_errorbar_with_partial_columns(self):
  2069. df = DataFrame(np.random.randn(10, 3))
  2070. df_err = DataFrame(np.random.randn(10, 2), columns=[0, 2])
  2071. kinds = ['line', 'bar']
  2072. for kind in kinds:
  2073. ax = _check_plot_works(df.plot, yerr=df_err, kind=kind)
  2074. self._check_has_errorbars(ax, xerr=0, yerr=2)
  2075. ix = date_range('1/1/2000', periods=10, freq='M')
  2076. df.set_index(ix, inplace=True)
  2077. df_err.set_index(ix, inplace=True)
  2078. ax = _check_plot_works(df.plot, yerr=df_err, kind='line')
  2079. self._check_has_errorbars(ax, xerr=0, yerr=2)
  2080. d = {'x': np.arange(12), 'y': np.arange(12, 0, -1)}
  2081. df = DataFrame(d)
  2082. d_err = {'x': np.ones(12) * 0.2, 'z': np.ones(12) * 0.4}
  2083. df_err = DataFrame(d_err)
  2084. for err in [d_err, df_err]:
  2085. ax = _check_plot_works(df.plot, yerr=err)
  2086. self._check_has_errorbars(ax, xerr=0, yerr=1)
  2087. @pytest.mark.slow
  2088. def test_errorbar_timeseries(self):
  2089. with warnings.catch_warnings():
  2090. d = {'x': np.arange(12), 'y': np.arange(12, 0, -1)}
  2091. d_err = {'x': np.ones(12) * 0.2, 'y': np.ones(12) * 0.4}
  2092. # check time-series plots
  2093. ix = date_range('1/1/2000', '1/1/2001', freq='M')
  2094. tdf = DataFrame(d, index=ix)
  2095. tdf_err = DataFrame(d_err, index=ix)
  2096. kinds = ['line', 'bar', 'barh']
  2097. for kind in kinds:
  2098. ax = _check_plot_works(tdf.plot, yerr=tdf_err, kind=kind)
  2099. self._check_has_errorbars(ax, xerr=0, yerr=2)
  2100. ax = _check_plot_works(tdf.plot, yerr=d_err, kind=kind)
  2101. self._check_has_errorbars(ax, xerr=0, yerr=2)
  2102. ax = _check_plot_works(tdf.plot, y='y', yerr=tdf_err['x'],
  2103. kind=kind)
  2104. self._check_has_errorbars(ax, xerr=0, yerr=1)
  2105. ax = _check_plot_works(tdf.plot, y='y', yerr='x', kind=kind)
  2106. self._check_has_errorbars(ax, xerr=0, yerr=1)
  2107. ax = _check_plot_works(tdf.plot, yerr=tdf_err, kind=kind)
  2108. self._check_has_errorbars(ax, xerr=0, yerr=2)
  2109. # _check_plot_works adds an ax so catch warning. see GH #13188
  2110. axes = _check_plot_works(tdf.plot,
  2111. kind=kind, yerr=tdf_err,
  2112. subplots=True)
  2113. self._check_has_errorbars(axes, xerr=0, yerr=1)
  2114. def test_errorbar_asymmetrical(self):
  2115. np.random.seed(0)
  2116. err = np.random.rand(3, 2, 5)
  2117. # each column is [0, 1, 2, 3, 4], [3, 4, 5, 6, 7]...
  2118. df = DataFrame(np.arange(15).reshape(3, 5)).T
  2119. ax = df.plot(yerr=err, xerr=err / 2)
  2120. yerr_0_0 = ax.collections[1].get_paths()[0].vertices[:, 1]
  2121. expected_0_0 = err[0, :, 0] * np.array([-1, 1])
  2122. tm.assert_almost_equal(yerr_0_0, expected_0_0)
  2123. with pytest.raises(ValueError):
  2124. df.plot(yerr=err.T)
  2125. tm.close()
  2126. # This XPASSES when tested with mpl == 3.0.1
  2127. @td.xfail_if_mpl_2_2
  2128. def test_table(self):
  2129. df = DataFrame(np.random.rand(10, 3),
  2130. index=list(string.ascii_letters[:10]))
  2131. _check_plot_works(df.plot, table=True)
  2132. _check_plot_works(df.plot, table=df)
  2133. ax = df.plot()
  2134. assert len(ax.tables) == 0
  2135. plotting.table(ax, df.T)
  2136. assert len(ax.tables) == 1
  2137. def test_errorbar_scatter(self):
  2138. df = DataFrame(
  2139. np.random.randn(5, 2), index=range(5), columns=['x', 'y'])
  2140. df_err = DataFrame(np.random.randn(5, 2) / 5,
  2141. index=range(5), columns=['x', 'y'])
  2142. ax = _check_plot_works(df.plot.scatter, x='x', y='y')
  2143. self._check_has_errorbars(ax, xerr=0, yerr=0)
  2144. ax = _check_plot_works(df.plot.scatter, x='x', y='y', xerr=df_err)
  2145. self._check_has_errorbars(ax, xerr=1, yerr=0)
  2146. ax = _check_plot_works(df.plot.scatter, x='x', y='y', yerr=df_err)
  2147. self._check_has_errorbars(ax, xerr=0, yerr=1)
  2148. ax = _check_plot_works(df.plot.scatter, x='x', y='y', xerr=df_err,
  2149. yerr=df_err)
  2150. self._check_has_errorbars(ax, xerr=1, yerr=1)
  2151. def _check_errorbar_color(containers, expected, has_err='has_xerr'):
  2152. lines = []
  2153. errs = [c.lines
  2154. for c in ax.containers if getattr(c, has_err, False)][0]
  2155. for el in errs:
  2156. if is_list_like(el):
  2157. lines.extend(el)
  2158. else:
  2159. lines.append(el)
  2160. err_lines = [x for x in lines if x in ax.collections]
  2161. self._check_colors(
  2162. err_lines, linecolors=np.array([expected] * len(err_lines)))
  2163. # GH 8081
  2164. df = DataFrame(
  2165. np.random.randn(10, 5), columns=['a', 'b', 'c', 'd', 'e'])
  2166. ax = df.plot.scatter(x='a', y='b', xerr='d', yerr='e', c='red')
  2167. self._check_has_errorbars(ax, xerr=1, yerr=1)
  2168. _check_errorbar_color(ax.containers, 'red', has_err='has_xerr')
  2169. _check_errorbar_color(ax.containers, 'red', has_err='has_yerr')
  2170. ax = df.plot.scatter(x='a', y='b', yerr='e', color='green')
  2171. self._check_has_errorbars(ax, xerr=0, yerr=1)
  2172. _check_errorbar_color(ax.containers, 'green', has_err='has_yerr')
  2173. @pytest.mark.slow
  2174. def test_sharex_and_ax(self):
  2175. # https://github.com/pandas-dev/pandas/issues/9737 using gridspec,
  2176. # the axis in fig.get_axis() are sorted differently than pandas
  2177. # expected them, so make sure that only the right ones are removed
  2178. import matplotlib.pyplot as plt
  2179. plt.close('all')
  2180. gs, axes = _generate_4_axes_via_gridspec()
  2181. df = DataFrame({"a": [1, 2, 3, 4, 5, 6],
  2182. "b": [1, 2, 3, 4, 5, 6],
  2183. "c": [1, 2, 3, 4, 5, 6],
  2184. "d": [1, 2, 3, 4, 5, 6]})
  2185. def _check(axes):
  2186. for ax in axes:
  2187. assert len(ax.lines) == 1
  2188. self._check_visible(ax.get_yticklabels(), visible=True)
  2189. for ax in [axes[0], axes[2]]:
  2190. self._check_visible(ax.get_xticklabels(), visible=False)
  2191. self._check_visible(
  2192. ax.get_xticklabels(minor=True), visible=False)
  2193. for ax in [axes[1], axes[3]]:
  2194. self._check_visible(ax.get_xticklabels(), visible=True)
  2195. self._check_visible(
  2196. ax.get_xticklabels(minor=True), visible=True)
  2197. for ax in axes:
  2198. df.plot(x="a", y="b", title="title", ax=ax, sharex=True)
  2199. gs.tight_layout(plt.gcf())
  2200. _check(axes)
  2201. tm.close()
  2202. gs, axes = _generate_4_axes_via_gridspec()
  2203. with tm.assert_produces_warning(UserWarning):
  2204. axes = df.plot(subplots=True, ax=axes, sharex=True)
  2205. _check(axes)
  2206. tm.close()
  2207. gs, axes = _generate_4_axes_via_gridspec()
  2208. # without sharex, no labels should be touched!
  2209. for ax in axes:
  2210. df.plot(x="a", y="b", title="title", ax=ax)
  2211. gs.tight_layout(plt.gcf())
  2212. for ax in axes:
  2213. assert len(ax.lines) == 1
  2214. self._check_visible(ax.get_yticklabels(), visible=True)
  2215. self._check_visible(ax.get_xticklabels(), visible=True)
  2216. self._check_visible(ax.get_xticklabels(minor=True), visible=True)
  2217. tm.close()
  2218. @pytest.mark.slow
  2219. def test_sharey_and_ax(self):
  2220. # https://github.com/pandas-dev/pandas/issues/9737 using gridspec,
  2221. # the axis in fig.get_axis() are sorted differently than pandas
  2222. # expected them, so make sure that only the right ones are removed
  2223. import matplotlib.pyplot as plt
  2224. gs, axes = _generate_4_axes_via_gridspec()
  2225. df = DataFrame({"a": [1, 2, 3, 4, 5, 6],
  2226. "b": [1, 2, 3, 4, 5, 6],
  2227. "c": [1, 2, 3, 4, 5, 6],
  2228. "d": [1, 2, 3, 4, 5, 6]})
  2229. def _check(axes):
  2230. for ax in axes:
  2231. assert len(ax.lines) == 1
  2232. self._check_visible(ax.get_xticklabels(), visible=True)
  2233. self._check_visible(
  2234. ax.get_xticklabels(minor=True), visible=True)
  2235. for ax in [axes[0], axes[1]]:
  2236. self._check_visible(ax.get_yticklabels(), visible=True)
  2237. for ax in [axes[2], axes[3]]:
  2238. self._check_visible(ax.get_yticklabels(), visible=False)
  2239. for ax in axes:
  2240. df.plot(x="a", y="b", title="title", ax=ax, sharey=True)
  2241. gs.tight_layout(plt.gcf())
  2242. _check(axes)
  2243. tm.close()
  2244. gs, axes = _generate_4_axes_via_gridspec()
  2245. with tm.assert_produces_warning(UserWarning):
  2246. axes = df.plot(subplots=True, ax=axes, sharey=True)
  2247. gs.tight_layout(plt.gcf())
  2248. _check(axes)
  2249. tm.close()
  2250. gs, axes = _generate_4_axes_via_gridspec()
  2251. # without sharex, no labels should be touched!
  2252. for ax in axes:
  2253. df.plot(x="a", y="b", title="title", ax=ax)
  2254. gs.tight_layout(plt.gcf())
  2255. for ax in axes:
  2256. assert len(ax.lines) == 1
  2257. self._check_visible(ax.get_yticklabels(), visible=True)
  2258. self._check_visible(ax.get_xticklabels(), visible=True)
  2259. self._check_visible(ax.get_xticklabels(minor=True), visible=True)
  2260. def test_memory_leak(self):
  2261. """ Check that every plot type gets properly collected. """
  2262. import weakref
  2263. import gc
  2264. results = {}
  2265. for kind in plotting._core._plot_klass.keys():
  2266. if not _ok_for_gaussian_kde(kind):
  2267. continue
  2268. args = {}
  2269. if kind in ['hexbin', 'scatter', 'pie']:
  2270. df = self.hexbin_df
  2271. args = {'x': 'A', 'y': 'B'}
  2272. elif kind == 'area':
  2273. df = self.tdf.abs()
  2274. else:
  2275. df = self.tdf
  2276. # Use a weakref so we can see if the object gets collected without
  2277. # also preventing it from being collected
  2278. results[kind] = weakref.proxy(df.plot(kind=kind, **args))
  2279. # have matplotlib delete all the figures
  2280. tm.close()
  2281. # force a garbage collection
  2282. gc.collect()
  2283. for key in results:
  2284. # check that every plot was collected
  2285. with pytest.raises(ReferenceError):
  2286. # need to actually access something to get an error
  2287. results[key].lines
  2288. @pytest.mark.slow
  2289. def test_df_subplots_patterns_minorticks(self):
  2290. # GH 10657
  2291. import matplotlib.pyplot as plt
  2292. df = DataFrame(np.random.randn(10, 2),
  2293. index=date_range('1/1/2000', periods=10),
  2294. columns=list('AB'))
  2295. # shared subplots
  2296. fig, axes = plt.subplots(2, 1, sharex=True)
  2297. axes = df.plot(subplots=True, ax=axes)
  2298. for ax in axes:
  2299. assert len(ax.lines) == 1
  2300. self._check_visible(ax.get_yticklabels(), visible=True)
  2301. # xaxis of 1st ax must be hidden
  2302. self._check_visible(axes[0].get_xticklabels(), visible=False)
  2303. self._check_visible(axes[0].get_xticklabels(minor=True), visible=False)
  2304. self._check_visible(axes[1].get_xticklabels(), visible=True)
  2305. self._check_visible(axes[1].get_xticklabels(minor=True), visible=True)
  2306. tm.close()
  2307. fig, axes = plt.subplots(2, 1)
  2308. with tm.assert_produces_warning(UserWarning):
  2309. axes = df.plot(subplots=True, ax=axes, sharex=True)
  2310. for ax in axes:
  2311. assert len(ax.lines) == 1
  2312. self._check_visible(ax.get_yticklabels(), visible=True)
  2313. # xaxis of 1st ax must be hidden
  2314. self._check_visible(axes[0].get_xticklabels(), visible=False)
  2315. self._check_visible(axes[0].get_xticklabels(minor=True), visible=False)
  2316. self._check_visible(axes[1].get_xticklabels(), visible=True)
  2317. self._check_visible(axes[1].get_xticklabels(minor=True), visible=True)
  2318. tm.close()
  2319. # not shared
  2320. fig, axes = plt.subplots(2, 1)
  2321. axes = df.plot(subplots=True, ax=axes)
  2322. for ax in axes:
  2323. assert len(ax.lines) == 1
  2324. self._check_visible(ax.get_yticklabels(), visible=True)
  2325. self._check_visible(ax.get_xticklabels(), visible=True)
  2326. self._check_visible(ax.get_xticklabels(minor=True), visible=True)
  2327. tm.close()
  2328. @pytest.mark.slow
  2329. def test_df_gridspec_patterns(self):
  2330. # GH 10819
  2331. import matplotlib.pyplot as plt
  2332. import matplotlib.gridspec as gridspec
  2333. ts = Series(np.random.randn(10),
  2334. index=date_range('1/1/2000', periods=10))
  2335. df = DataFrame(np.random.randn(10, 2), index=ts.index,
  2336. columns=list('AB'))
  2337. def _get_vertical_grid():
  2338. gs = gridspec.GridSpec(3, 1)
  2339. fig = plt.figure()
  2340. ax1 = fig.add_subplot(gs[:2, :])
  2341. ax2 = fig.add_subplot(gs[2, :])
  2342. return ax1, ax2
  2343. def _get_horizontal_grid():
  2344. gs = gridspec.GridSpec(1, 3)
  2345. fig = plt.figure()
  2346. ax1 = fig.add_subplot(gs[:, :2])
  2347. ax2 = fig.add_subplot(gs[:, 2])
  2348. return ax1, ax2
  2349. for ax1, ax2 in [_get_vertical_grid(), _get_horizontal_grid()]:
  2350. ax1 = ts.plot(ax=ax1)
  2351. assert len(ax1.lines) == 1
  2352. ax2 = df.plot(ax=ax2)
  2353. assert len(ax2.lines) == 2
  2354. for ax in [ax1, ax2]:
  2355. self._check_visible(ax.get_yticklabels(), visible=True)
  2356. self._check_visible(ax.get_xticklabels(), visible=True)
  2357. self._check_visible(
  2358. ax.get_xticklabels(minor=True), visible=True)
  2359. tm.close()
  2360. # subplots=True
  2361. for ax1, ax2 in [_get_vertical_grid(), _get_horizontal_grid()]:
  2362. axes = df.plot(subplots=True, ax=[ax1, ax2])
  2363. assert len(ax1.lines) == 1
  2364. assert len(ax2.lines) == 1
  2365. for ax in axes:
  2366. self._check_visible(ax.get_yticklabels(), visible=True)
  2367. self._check_visible(ax.get_xticklabels(), visible=True)
  2368. self._check_visible(
  2369. ax.get_xticklabels(minor=True), visible=True)
  2370. tm.close()
  2371. # vertical / subplots / sharex=True / sharey=True
  2372. ax1, ax2 = _get_vertical_grid()
  2373. with tm.assert_produces_warning(UserWarning):
  2374. axes = df.plot(subplots=True, ax=[ax1, ax2], sharex=True,
  2375. sharey=True)
  2376. assert len(axes[0].lines) == 1
  2377. assert len(axes[1].lines) == 1
  2378. for ax in [ax1, ax2]:
  2379. # yaxis are visible because there is only one column
  2380. self._check_visible(ax.get_yticklabels(), visible=True)
  2381. # xaxis of axes0 (top) are hidden
  2382. self._check_visible(axes[0].get_xticklabels(), visible=False)
  2383. self._check_visible(axes[0].get_xticklabels(minor=True), visible=False)
  2384. self._check_visible(axes[1].get_xticklabels(), visible=True)
  2385. self._check_visible(axes[1].get_xticklabels(minor=True), visible=True)
  2386. tm.close()
  2387. # horizontal / subplots / sharex=True / sharey=True
  2388. ax1, ax2 = _get_horizontal_grid()
  2389. with tm.assert_produces_warning(UserWarning):
  2390. axes = df.plot(subplots=True, ax=[ax1, ax2], sharex=True,
  2391. sharey=True)
  2392. assert len(axes[0].lines) == 1
  2393. assert len(axes[1].lines) == 1
  2394. self._check_visible(axes[0].get_yticklabels(), visible=True)
  2395. # yaxis of axes1 (right) are hidden
  2396. self._check_visible(axes[1].get_yticklabels(), visible=False)
  2397. for ax in [ax1, ax2]:
  2398. # xaxis are visible because there is only one column
  2399. self._check_visible(ax.get_xticklabels(), visible=True)
  2400. self._check_visible(ax.get_xticklabels(minor=True), visible=True)
  2401. tm.close()
  2402. # boxed
  2403. def _get_boxed_grid():
  2404. gs = gridspec.GridSpec(3, 3)
  2405. fig = plt.figure()
  2406. ax1 = fig.add_subplot(gs[:2, :2])
  2407. ax2 = fig.add_subplot(gs[:2, 2])
  2408. ax3 = fig.add_subplot(gs[2, :2])
  2409. ax4 = fig.add_subplot(gs[2, 2])
  2410. return ax1, ax2, ax3, ax4
  2411. axes = _get_boxed_grid()
  2412. df = DataFrame(np.random.randn(10, 4),
  2413. index=ts.index, columns=list('ABCD'))
  2414. axes = df.plot(subplots=True, ax=axes)
  2415. for ax in axes:
  2416. assert len(ax.lines) == 1
  2417. # axis are visible because these are not shared
  2418. self._check_visible(ax.get_yticklabels(), visible=True)
  2419. self._check_visible(ax.get_xticklabels(), visible=True)
  2420. self._check_visible(ax.get_xticklabels(minor=True), visible=True)
  2421. tm.close()
  2422. # subplots / sharex=True / sharey=True
  2423. axes = _get_boxed_grid()
  2424. with tm.assert_produces_warning(UserWarning):
  2425. axes = df.plot(subplots=True, ax=axes, sharex=True, sharey=True)
  2426. for ax in axes:
  2427. assert len(ax.lines) == 1
  2428. for ax in [axes[0], axes[2]]: # left column
  2429. self._check_visible(ax.get_yticklabels(), visible=True)
  2430. for ax in [axes[1], axes[3]]: # right column
  2431. self._check_visible(ax.get_yticklabels(), visible=False)
  2432. for ax in [axes[0], axes[1]]: # top row
  2433. self._check_visible(ax.get_xticklabels(), visible=False)
  2434. self._check_visible(ax.get_xticklabels(minor=True), visible=False)
  2435. for ax in [axes[2], axes[3]]: # bottom row
  2436. self._check_visible(ax.get_xticklabels(), visible=True)
  2437. self._check_visible(ax.get_xticklabels(minor=True), visible=True)
  2438. tm.close()
  2439. @pytest.mark.slow
  2440. def test_df_grid_settings(self):
  2441. # Make sure plot defaults to rcParams['axes.grid'] setting, GH 9792
  2442. self._check_grid_settings(
  2443. DataFrame({'a': [1, 2, 3], 'b': [2, 3, 4]}),
  2444. plotting._core._dataframe_kinds, kws={'x': 'a', 'y': 'b'})
  2445. def test_invalid_colormap(self):
  2446. df = DataFrame(randn(3, 2), columns=['A', 'B'])
  2447. with pytest.raises(ValueError):
  2448. df.plot(colormap='invalid_colormap')
  2449. def test_plain_axes(self):
  2450. # supplied ax itself is a SubplotAxes, but figure contains also
  2451. # a plain Axes object (GH11556)
  2452. fig, ax = self.plt.subplots()
  2453. fig.add_axes([0.2, 0.2, 0.2, 0.2])
  2454. Series(rand(10)).plot(ax=ax)
  2455. # suppliad ax itself is a plain Axes, but because the cmap keyword
  2456. # a new ax is created for the colorbar -> also multiples axes (GH11520)
  2457. df = DataFrame({'a': randn(8), 'b': randn(8)})
  2458. fig = self.plt.figure()
  2459. ax = fig.add_axes((0, 0, 1, 1))
  2460. df.plot(kind='scatter', ax=ax, x='a', y='b', c='a', cmap='hsv')
  2461. # other examples
  2462. fig, ax = self.plt.subplots()
  2463. from mpl_toolkits.axes_grid1 import make_axes_locatable
  2464. divider = make_axes_locatable(ax)
  2465. cax = divider.append_axes("right", size="5%", pad=0.05)
  2466. Series(rand(10)).plot(ax=ax)
  2467. Series(rand(10)).plot(ax=cax)
  2468. fig, ax = self.plt.subplots()
  2469. from mpl_toolkits.axes_grid1.inset_locator import inset_axes
  2470. iax = inset_axes(ax, width="30%", height=1., loc=3)
  2471. Series(rand(10)).plot(ax=ax)
  2472. Series(rand(10)).plot(ax=iax)
  2473. def test_passed_bar_colors(self):
  2474. import matplotlib as mpl
  2475. color_tuples = [(0.9, 0, 0, 1), (0, 0.9, 0, 1), (0, 0, 0.9, 1)]
  2476. colormap = mpl.colors.ListedColormap(color_tuples)
  2477. barplot = pd.DataFrame([[1, 2, 3]]).plot(kind="bar", cmap=colormap)
  2478. assert color_tuples == [c.get_facecolor() for c in barplot.patches]
  2479. def test_rcParams_bar_colors(self):
  2480. import matplotlib as mpl
  2481. color_tuples = [(0.9, 0, 0, 1), (0, 0.9, 0, 1), (0, 0, 0.9, 1)]
  2482. with mpl.rc_context(
  2483. rc={'axes.prop_cycle': mpl.cycler("color", color_tuples)}):
  2484. barplot = pd.DataFrame([[1, 2, 3]]).plot(kind="bar")
  2485. assert color_tuples == [c.get_facecolor() for c in barplot.patches]
  2486. @pytest.mark.parametrize('method', ['line', 'barh', 'bar'])
  2487. def test_secondary_axis_font_size(self, method):
  2488. # GH: 12565
  2489. df = (pd.DataFrame(np.random.randn(15, 2),
  2490. columns=list('AB'))
  2491. .assign(C=lambda df: df.B.cumsum())
  2492. .assign(D=lambda df: df.C * 1.1))
  2493. fontsize = 20
  2494. sy = ['C', 'D']
  2495. kwargs = dict(secondary_y=sy, fontsize=fontsize,
  2496. mark_right=True)
  2497. ax = getattr(df.plot, method)(**kwargs)
  2498. self._check_ticks_props(axes=ax.right_ax,
  2499. ylabelsize=fontsize)
  2500. def _generate_4_axes_via_gridspec():
  2501. import matplotlib.pyplot as plt
  2502. import matplotlib as mpl
  2503. import matplotlib.gridspec # noqa
  2504. gs = mpl.gridspec.GridSpec(2, 2)
  2505. ax_tl = plt.subplot(gs[0, 0])
  2506. ax_ll = plt.subplot(gs[1, 0])
  2507. ax_tr = plt.subplot(gs[0, 1])
  2508. ax_lr = plt.subplot(gs[1, 1])
  2509. return gs, [ax_tl, ax_ll, ax_tr, ax_lr]