test_axes.py 211 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676
  1. from collections import namedtuple
  2. from itertools import product
  3. from distutils.version import LooseVersion
  4. import io
  5. import platform
  6. import datetime
  7. import dateutil.tz as dutz
  8. import numpy as np
  9. from numpy import ma
  10. from cycler import cycler
  11. from decimal import Decimal
  12. import pytest
  13. import warnings
  14. import matplotlib
  15. import matplotlib as mpl
  16. from matplotlib.testing.decorators import (
  17. image_comparison, check_figures_equal, remove_ticks_and_titles)
  18. import matplotlib.pyplot as plt
  19. import matplotlib.markers as mmarkers
  20. import matplotlib.patches as mpatches
  21. import matplotlib.colors as mcolors
  22. import matplotlib.ticker as mticker
  23. import matplotlib.transforms as mtransforms
  24. from numpy.testing import (
  25. assert_allclose, assert_array_equal, assert_array_almost_equal)
  26. from matplotlib import rc_context
  27. from matplotlib.cbook import (
  28. IgnoredKeywordWarning, MatplotlibDeprecationWarning)
  29. # Note: Some test cases are run twice: once normally and once with labeled data
  30. # These two must be defined in the same test function or need to have
  31. # different baseline images to prevent race conditions when pytest runs
  32. # the tests with multiple threads.
  33. def test_get_labels():
  34. fig, ax = plt.subplots()
  35. ax.set_xlabel('x label')
  36. ax.set_ylabel('y label')
  37. assert ax.get_xlabel() == 'x label'
  38. assert ax.get_ylabel() == 'y label'
  39. @image_comparison(['acorr.png'], style='mpl20')
  40. def test_acorr():
  41. # Remove this line when this test image is regenerated.
  42. plt.rcParams['text.kerning_factor'] = 6
  43. np.random.seed(19680801)
  44. n = 512
  45. x = np.random.normal(0, 1, n).cumsum()
  46. fig, ax = plt.subplots()
  47. ax.acorr(x, maxlags=n - 1, label='acorr')
  48. ax.legend()
  49. @image_comparison(['spy.png'], style='mpl20')
  50. def test_spy():
  51. np.random.seed(19680801)
  52. a = np.ones(32 * 32)
  53. a[:16 * 32] = 0
  54. np.random.shuffle(a)
  55. a = np.reshape(a, (32, 32))
  56. fig, ax = plt.subplots()
  57. ax.spy(a)
  58. def test_spy_invalid_kwargs():
  59. fig, ax = plt.subplots()
  60. for unsupported_kw in [{'interpolation': 'nearest'},
  61. {'marker': 'o', 'linestyle': 'solid'}]:
  62. with pytest.raises(TypeError):
  63. ax.spy(np.eye(3, 3), **unsupported_kw)
  64. @image_comparison(['matshow.png'], style='mpl20')
  65. def test_matshow():
  66. np.random.seed(19680801)
  67. a = np.random.rand(32, 32)
  68. fig, ax = plt.subplots()
  69. ax.matshow(a)
  70. @image_comparison(['formatter_ticker_001',
  71. 'formatter_ticker_002',
  72. 'formatter_ticker_003',
  73. 'formatter_ticker_004',
  74. 'formatter_ticker_005',
  75. ])
  76. def test_formatter_ticker():
  77. import matplotlib.testing.jpl_units as units
  78. units.register()
  79. # This should affect the tick size. (Tests issue #543)
  80. matplotlib.rcParams['lines.markeredgewidth'] = 30
  81. # This essentially test to see if user specified labels get overwritten
  82. # by the auto labeler functionality of the axes.
  83. xdata = [x*units.sec for x in range(10)]
  84. ydata1 = [(1.5*y - 0.5)*units.km for y in range(10)]
  85. ydata2 = [(1.75*y - 1.0)*units.km for y in range(10)]
  86. ax = plt.figure().subplots()
  87. ax.set_xlabel("x-label 001")
  88. ax = plt.figure().subplots()
  89. ax.set_xlabel("x-label 001")
  90. ax.plot(xdata, ydata1, color='blue', xunits="sec")
  91. ax = plt.figure().subplots()
  92. ax.set_xlabel("x-label 001")
  93. ax.plot(xdata, ydata1, color='blue', xunits="sec")
  94. ax.set_xlabel("x-label 003")
  95. ax = plt.figure().subplots()
  96. ax.plot(xdata, ydata1, color='blue', xunits="sec")
  97. ax.plot(xdata, ydata2, color='green', xunits="hour")
  98. ax.set_xlabel("x-label 004")
  99. # See SF bug 2846058
  100. # https://sourceforge.net/tracker/?func=detail&aid=2846058&group_id=80706&atid=560720
  101. ax = plt.figure().subplots()
  102. ax.plot(xdata, ydata1, color='blue', xunits="sec")
  103. ax.plot(xdata, ydata2, color='green', xunits="hour")
  104. ax.set_xlabel("x-label 005")
  105. ax.autoscale_view()
  106. @image_comparison(["twin_axis_locators_formatters"])
  107. def test_twin_axis_locators_formatters():
  108. vals = np.linspace(0, 1, num=5, endpoint=True)
  109. locs = np.sin(np.pi * vals / 2.0)
  110. majl = plt.FixedLocator(locs)
  111. minl = plt.FixedLocator([0.1, 0.2, 0.3])
  112. fig = plt.figure()
  113. ax1 = fig.add_subplot(1, 1, 1)
  114. ax1.plot([0.1, 100], [0, 1])
  115. ax1.yaxis.set_major_locator(majl)
  116. ax1.yaxis.set_minor_locator(minl)
  117. ax1.yaxis.set_major_formatter(plt.FormatStrFormatter('%08.2lf'))
  118. ax1.yaxis.set_minor_formatter(plt.FixedFormatter(['tricks', 'mind',
  119. 'jedi']))
  120. ax1.xaxis.set_major_locator(plt.LinearLocator())
  121. ax1.xaxis.set_minor_locator(plt.FixedLocator([15, 35, 55, 75]))
  122. ax1.xaxis.set_major_formatter(plt.FormatStrFormatter('%05.2lf'))
  123. ax1.xaxis.set_minor_formatter(plt.FixedFormatter(['c', '3', 'p', 'o']))
  124. ax1.twiny()
  125. ax1.twinx()
  126. def test_twinx_cla():
  127. fig, ax = plt.subplots()
  128. ax2 = ax.twinx()
  129. ax3 = ax2.twiny()
  130. plt.draw()
  131. assert not ax2.xaxis.get_visible()
  132. assert not ax2.patch.get_visible()
  133. ax2.cla()
  134. ax3.cla()
  135. assert not ax2.xaxis.get_visible()
  136. assert not ax2.patch.get_visible()
  137. assert ax2.yaxis.get_visible()
  138. assert ax3.xaxis.get_visible()
  139. assert not ax3.patch.get_visible()
  140. assert not ax3.yaxis.get_visible()
  141. assert ax.xaxis.get_visible()
  142. assert ax.patch.get_visible()
  143. assert ax.yaxis.get_visible()
  144. @image_comparison(['twin_autoscale.png'])
  145. def test_twinx_axis_scales():
  146. x = np.array([0, 0.5, 1])
  147. y = 0.5 * x
  148. x2 = np.array([0, 1, 2])
  149. y2 = 2 * x2
  150. fig = plt.figure()
  151. ax = fig.add_axes((0, 0, 1, 1), autoscalex_on=False, autoscaley_on=False)
  152. ax.plot(x, y, color='blue', lw=10)
  153. ax2 = plt.twinx(ax)
  154. ax2.plot(x2, y2, 'r--', lw=5)
  155. ax.margins(0, 0)
  156. ax2.margins(0, 0)
  157. def test_twin_inherit_autoscale_setting():
  158. fig, ax = plt.subplots()
  159. ax_x_on = ax.twinx()
  160. ax.set_autoscalex_on(False)
  161. ax_x_off = ax.twinx()
  162. assert ax_x_on.get_autoscalex_on()
  163. assert not ax_x_off.get_autoscalex_on()
  164. ax_y_on = ax.twiny()
  165. ax.set_autoscaley_on(False)
  166. ax_y_off = ax.twiny()
  167. assert ax_y_on.get_autoscaley_on()
  168. assert not ax_y_off.get_autoscaley_on()
  169. def test_inverted_cla():
  170. # GitHub PR #5450. Setting autoscale should reset
  171. # axes to be non-inverted.
  172. # plotting an image, then 1d graph, axis is now down
  173. fig = plt.figure(0)
  174. ax = fig.gca()
  175. # 1. test that a new axis is not inverted per default
  176. assert not ax.xaxis_inverted()
  177. assert not ax.yaxis_inverted()
  178. img = np.random.random((100, 100))
  179. ax.imshow(img)
  180. # 2. test that a image axis is inverted
  181. assert not ax.xaxis_inverted()
  182. assert ax.yaxis_inverted()
  183. # 3. test that clearing and plotting a line, axes are
  184. # not inverted
  185. ax.cla()
  186. x = np.linspace(0, 2*np.pi, 100)
  187. ax.plot(x, np.cos(x))
  188. assert not ax.xaxis_inverted()
  189. assert not ax.yaxis_inverted()
  190. # 4. autoscaling should not bring back axes to normal
  191. ax.cla()
  192. ax.imshow(img)
  193. plt.autoscale()
  194. assert not ax.xaxis_inverted()
  195. assert ax.yaxis_inverted()
  196. # 5. two shared axes. Inverting the master axis should invert the shared
  197. # axes; clearing the master axis should bring axes in shared
  198. # axes back to normal.
  199. ax0 = plt.subplot(211)
  200. ax1 = plt.subplot(212, sharey=ax0)
  201. ax0.yaxis.set_inverted(True)
  202. assert ax1.yaxis_inverted()
  203. ax1.plot(x, np.cos(x))
  204. ax0.cla()
  205. assert not ax1.yaxis_inverted()
  206. ax1.cla()
  207. # 6. clearing the nonmaster should not touch limits
  208. ax0.imshow(img)
  209. ax1.plot(x, np.cos(x))
  210. ax1.cla()
  211. assert ax.yaxis_inverted()
  212. # clean up
  213. plt.close(fig)
  214. @check_figures_equal(extensions=["png"])
  215. def test_minorticks_on_rcParams_both(fig_test, fig_ref):
  216. with matplotlib.rc_context({"xtick.minor.visible": True,
  217. "ytick.minor.visible": True}):
  218. ax_test = fig_test.subplots()
  219. ax_test.plot([0, 1], [0, 1])
  220. ax_ref = fig_ref.subplots()
  221. ax_ref.plot([0, 1], [0, 1])
  222. ax_ref.minorticks_on()
  223. @image_comparison(["autoscale_tiny_range"], remove_text=True)
  224. def test_autoscale_tiny_range():
  225. # github pull #904
  226. fig, axs = plt.subplots(2, 2)
  227. for i, ax in enumerate(axs.flat):
  228. y1 = 10**(-11 - i)
  229. ax.plot([0, 1], [1, 1 + y1])
  230. @pytest.mark.style('default')
  231. def test_autoscale_tight():
  232. fig, ax = plt.subplots(1, 1)
  233. ax.plot([1, 2, 3, 4])
  234. ax.autoscale(enable=True, axis='x', tight=False)
  235. ax.autoscale(enable=True, axis='y', tight=True)
  236. assert_allclose(ax.get_xlim(), (-0.15, 3.15))
  237. assert_allclose(ax.get_ylim(), (1.0, 4.0))
  238. @pytest.mark.style('default')
  239. def test_autoscale_log_shared():
  240. # related to github #7587
  241. # array starts at zero to trigger _minpos handling
  242. x = np.arange(100, dtype=float)
  243. fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)
  244. ax1.loglog(x, x)
  245. ax2.semilogx(x, x)
  246. ax1.autoscale(tight=True)
  247. ax2.autoscale(tight=True)
  248. plt.draw()
  249. lims = (x[1], x[-1])
  250. assert_allclose(ax1.get_xlim(), lims)
  251. assert_allclose(ax1.get_ylim(), lims)
  252. assert_allclose(ax2.get_xlim(), lims)
  253. assert_allclose(ax2.get_ylim(), (x[0], x[-1]))
  254. @pytest.mark.style('default')
  255. def test_use_sticky_edges():
  256. fig, ax = plt.subplots()
  257. ax.imshow([[0, 1], [2, 3]], origin='lower')
  258. assert_allclose(ax.get_xlim(), (-0.5, 1.5))
  259. assert_allclose(ax.get_ylim(), (-0.5, 1.5))
  260. ax.use_sticky_edges = False
  261. ax.autoscale()
  262. xlim = (-0.5 - 2 * ax._xmargin, 1.5 + 2 * ax._xmargin)
  263. ylim = (-0.5 - 2 * ax._ymargin, 1.5 + 2 * ax._ymargin)
  264. assert_allclose(ax.get_xlim(), xlim)
  265. assert_allclose(ax.get_ylim(), ylim)
  266. # Make sure it is reversible:
  267. ax.use_sticky_edges = True
  268. ax.autoscale()
  269. assert_allclose(ax.get_xlim(), (-0.5, 1.5))
  270. assert_allclose(ax.get_ylim(), (-0.5, 1.5))
  271. @check_figures_equal(extensions=["png"])
  272. def test_sticky_shared_axes(fig_test, fig_ref):
  273. # Check that sticky edges work whether they are set in an axes that is a
  274. # "master" in a share, or an axes that is a "follower".
  275. Z = np.arange(15).reshape(3, 5)
  276. ax0 = fig_test.add_subplot(211)
  277. ax1 = fig_test.add_subplot(212, sharex=ax0)
  278. ax1.pcolormesh(Z)
  279. ax0 = fig_ref.add_subplot(212)
  280. ax1 = fig_ref.add_subplot(211, sharex=ax0)
  281. ax0.pcolormesh(Z)
  282. @image_comparison(['offset_points'], remove_text=True)
  283. def test_basic_annotate():
  284. # Setup some data
  285. t = np.arange(0.0, 5.0, 0.01)
  286. s = np.cos(2.0*np.pi * t)
  287. # Offset Points
  288. fig = plt.figure()
  289. ax = fig.add_subplot(111, autoscale_on=False, xlim=(-1, 5), ylim=(-3, 5))
  290. line, = ax.plot(t, s, lw=3, color='purple')
  291. ax.annotate('local max', xy=(3, 1), xycoords='data',
  292. xytext=(3, 3), textcoords='offset points')
  293. @image_comparison(['arrow_simple.png'], remove_text=True)
  294. def test_arrow_simple():
  295. # Simple image test for ax.arrow
  296. # kwargs that take discrete values
  297. length_includes_head = (True, False)
  298. shape = ('full', 'left', 'right')
  299. head_starts_at_zero = (True, False)
  300. # Create outer product of values
  301. kwargs = product(length_includes_head, shape, head_starts_at_zero)
  302. fig, axs = plt.subplots(3, 4)
  303. for i, (ax, kwarg) in enumerate(zip(axs.flat, kwargs)):
  304. ax.set_xlim(-2, 2)
  305. ax.set_ylim(-2, 2)
  306. # Unpack kwargs
  307. (length_includes_head, shape, head_starts_at_zero) = kwarg
  308. theta = 2 * np.pi * i / 12
  309. # Draw arrow
  310. ax.arrow(0, 0, np.sin(theta), np.cos(theta),
  311. width=theta/100,
  312. length_includes_head=length_includes_head,
  313. shape=shape,
  314. head_starts_at_zero=head_starts_at_zero,
  315. head_width=theta / 10,
  316. head_length=theta / 10)
  317. def test_arrow_empty():
  318. _, ax = plt.subplots()
  319. # Create an empty FancyArrow
  320. ax.arrow(0, 0, 0, 0, head_length=0)
  321. def test_annotate_default_arrow():
  322. # Check that we can make an annotation arrow with only default properties.
  323. fig, ax = plt.subplots()
  324. ann = ax.annotate("foo", (0, 1), xytext=(2, 3))
  325. assert ann.arrow_patch is None
  326. ann = ax.annotate("foo", (0, 1), xytext=(2, 3), arrowprops={})
  327. assert ann.arrow_patch is not None
  328. @image_comparison(['polar_axes'], style='default')
  329. def test_polar_annotations():
  330. # you can specify the xypoint and the xytext in different
  331. # positions and coordinate systems, and optionally turn on a
  332. # connecting line and mark the point with a marker. Annotations
  333. # work on polar axes too. In the example below, the xy point is
  334. # in native coordinates (xycoords defaults to 'data'). For a
  335. # polar axes, this is in (theta, radius) space. The text in this
  336. # example is placed in the fractional figure coordinate system.
  337. # Text keyword args like horizontal and vertical alignment are
  338. # respected
  339. # Setup some data
  340. r = np.arange(0.0, 1.0, 0.001)
  341. theta = 2.0 * 2.0 * np.pi * r
  342. fig = plt.figure()
  343. ax = fig.add_subplot(111, polar=True)
  344. line, = ax.plot(theta, r, color='#ee8d18', lw=3)
  345. line, = ax.plot((0, 0), (0, 1), color="#0000ff", lw=1)
  346. ind = 800
  347. thisr, thistheta = r[ind], theta[ind]
  348. ax.plot([thistheta], [thisr], 'o')
  349. ax.annotate('a polar annotation',
  350. xy=(thistheta, thisr), # theta, radius
  351. xytext=(0.05, 0.05), # fraction, fraction
  352. textcoords='figure fraction',
  353. arrowprops=dict(facecolor='black', shrink=0.05),
  354. horizontalalignment='left',
  355. verticalalignment='baseline',
  356. )
  357. ax.tick_params(axis='x', tick1On=True, tick2On=True, direction='out')
  358. @image_comparison(['polar_coords'], style='default', remove_text=True)
  359. def test_polar_coord_annotations():
  360. # You can also use polar notation on a cartesian axes. Here the
  361. # native coordinate system ('data') is cartesian, so you need to
  362. # specify the xycoords and textcoords as 'polar' if you want to
  363. # use (theta, radius)
  364. from matplotlib.patches import Ellipse
  365. el = Ellipse((0, 0), 10, 20, facecolor='r', alpha=0.5)
  366. fig = plt.figure()
  367. ax = fig.add_subplot(111, aspect='equal')
  368. ax.add_artist(el)
  369. el.set_clip_box(ax.bbox)
  370. ax.annotate('the top',
  371. xy=(np.pi/2., 10.), # theta, radius
  372. xytext=(np.pi/3, 20.), # theta, radius
  373. xycoords='polar',
  374. textcoords='polar',
  375. arrowprops=dict(facecolor='black', shrink=0.05),
  376. horizontalalignment='left',
  377. verticalalignment='baseline',
  378. clip_on=True, # clip to the axes bounding box
  379. )
  380. ax.set_xlim(-20, 20)
  381. ax.set_ylim(-20, 20)
  382. @image_comparison(['polar_alignment.png'])
  383. def test_polar_alignment():
  384. """
  385. Test that changing the vertical/horizontal alignment of a polar graph
  386. works as expected.
  387. """
  388. angles = np.arange(0, 360, 90)
  389. grid_values = [0, 0.2, 0.4, 0.6, 0.8, 1]
  390. fig = plt.figure()
  391. rect = [0.1, 0.1, 0.8, 0.8]
  392. horizontal = fig.add_axes(rect, polar=True, label='horizontal')
  393. horizontal.set_thetagrids(angles)
  394. vertical = fig.add_axes(rect, polar=True, label='vertical')
  395. vertical.patch.set_visible(False)
  396. for i in range(2):
  397. fig.axes[i].set_rgrids(
  398. grid_values, angle=angles[i],
  399. horizontalalignment='left', verticalalignment='top')
  400. @image_comparison(['fill_units.png'], savefig_kwarg={'dpi': 60})
  401. def test_fill_units():
  402. from datetime import datetime
  403. import matplotlib.testing.jpl_units as units
  404. units.register()
  405. # generate some data
  406. t = units.Epoch("ET", dt=datetime(2009, 4, 27))
  407. value = 10.0 * units.deg
  408. day = units.Duration("ET", 24.0 * 60.0 * 60.0)
  409. fig = plt.figure()
  410. # Top-Left
  411. ax1 = fig.add_subplot(221)
  412. ax1.plot([t], [value], yunits='deg', color='red')
  413. ax1.fill([733525.0, 733525.0, 733526.0, 733526.0],
  414. [0.0, 0.0, 90.0, 0.0], 'b')
  415. # Top-Right
  416. ax2 = fig.add_subplot(222)
  417. ax2.plot([t], [value], yunits='deg', color='red')
  418. ax2.fill([t, t, t + day, t + day],
  419. [0.0, 0.0, 90.0, 0.0], 'b')
  420. # Bottom-Left
  421. ax3 = fig.add_subplot(223)
  422. ax3.plot([t], [value], yunits='deg', color='red')
  423. ax3.fill([733525.0, 733525.0, 733526.0, 733526.0],
  424. [0 * units.deg, 0 * units.deg, 90 * units.deg, 0 * units.deg],
  425. 'b')
  426. # Bottom-Right
  427. ax4 = fig.add_subplot(224)
  428. ax4.plot([t], [value], yunits='deg', color='red')
  429. ax4.fill([t, t, t + day, t + day],
  430. [0 * units.deg, 0 * units.deg, 90 * units.deg, 0 * units.deg],
  431. facecolor="blue")
  432. fig.autofmt_xdate()
  433. @image_comparison(['single_point', 'single_point'])
  434. def test_single_point():
  435. # Issue #1796: don't let lines.marker affect the grid
  436. matplotlib.rcParams['lines.marker'] = 'o'
  437. matplotlib.rcParams['axes.grid'] = True
  438. plt.figure()
  439. plt.subplot(211)
  440. plt.plot([0], [0], 'o')
  441. plt.subplot(212)
  442. plt.plot([1], [1], 'o')
  443. # Reuse testcase from above for a labeled data test
  444. data = {'a': [0], 'b': [1]}
  445. plt.figure()
  446. plt.subplot(211)
  447. plt.plot('a', 'a', 'o', data=data)
  448. plt.subplot(212)
  449. plt.plot('b', 'b', 'o', data=data)
  450. @image_comparison(['single_date.png'], style='mpl20')
  451. def test_single_date():
  452. # use former defaults to match existing baseline image
  453. plt.rcParams['axes.formatter.limits'] = -7, 7
  454. time1 = [721964.0]
  455. data1 = [-65.54]
  456. plt.subplot(211)
  457. plt.plot_date(time1, data1, 'o', color='r')
  458. plt.subplot(212)
  459. plt.plot(time1, data1, 'o', color='r')
  460. @image_comparison(['shaped_data'])
  461. def test_shaped_data():
  462. xdata = np.array([[0.53295185, 0.23052951, 0.19057629, 0.66724975,
  463. 0.96577916, 0.73136095, 0.60823287, 0.01792100,
  464. 0.29744742, 0.27164665],
  465. [0.27980120, 0.25814229, 0.02818193, 0.12966456,
  466. 0.57446277, 0.58167607, 0.71028245, 0.69112737,
  467. 0.89923072, 0.99072476],
  468. [0.81218578, 0.80464528, 0.76071809, 0.85616314,
  469. 0.12757994, 0.94324936, 0.73078663, 0.09658102,
  470. 0.60703967, 0.77664978],
  471. [0.28332265, 0.81479711, 0.86985333, 0.43797066,
  472. 0.32540082, 0.43819229, 0.92230363, 0.49414252,
  473. 0.68168256, 0.05922372],
  474. [0.10721335, 0.93904142, 0.79163075, 0.73232848,
  475. 0.90283839, 0.68408046, 0.25502302, 0.95976614,
  476. 0.59214115, 0.13663711],
  477. [0.28087456, 0.33127607, 0.15530412, 0.76558121,
  478. 0.83389773, 0.03735974, 0.98717738, 0.71432229,
  479. 0.54881366, 0.86893953],
  480. [0.77995937, 0.99555600, 0.29688434, 0.15646162,
  481. 0.05184800, 0.37161935, 0.12998491, 0.09377296,
  482. 0.36882507, 0.36583435],
  483. [0.37851836, 0.05315792, 0.63144617, 0.25003433,
  484. 0.69586032, 0.11393988, 0.92362096, 0.88045438,
  485. 0.93530252, 0.68275072],
  486. [0.86486596, 0.83236675, 0.82960664, 0.57796630,
  487. 0.25724233, 0.84841095, 0.90862812, 0.64414887,
  488. 0.35652720, 0.71026066],
  489. [0.01383268, 0.34060930, 0.76084285, 0.70800694,
  490. 0.87634056, 0.08213693, 0.54655021, 0.98123181,
  491. 0.44080053, 0.86815815]])
  492. y1 = np.arange(10).reshape((1, -1))
  493. y2 = np.arange(10).reshape((-1, 1))
  494. plt.subplot(411)
  495. plt.plot(y1)
  496. plt.subplot(412)
  497. plt.plot(y2)
  498. plt.subplot(413)
  499. with pytest.raises(ValueError):
  500. plt.plot((y1, y2))
  501. plt.subplot(414)
  502. plt.plot(xdata[:, 1], xdata[1, :], 'o')
  503. def test_structured_data():
  504. # support for structured data
  505. pts = np.array([(1, 1), (2, 2)], dtype=[("ones", float), ("twos", float)])
  506. # this should not read second name as a format and raise ValueError
  507. axs = plt.figure().subplots(2)
  508. axs[0].plot("ones", "twos", data=pts)
  509. axs[1].plot("ones", "twos", "r", data=pts)
  510. @image_comparison(['const_xy'])
  511. def test_const_xy():
  512. plt.subplot(311)
  513. plt.plot(np.arange(10), np.ones(10))
  514. plt.subplot(312)
  515. plt.plot(np.ones(10), np.arange(10))
  516. plt.subplot(313)
  517. plt.plot(np.ones(10), np.ones(10), 'o')
  518. def test_polar_twice():
  519. fig = plt.figure()
  520. plt.polar([1, 2], [.1, .2])
  521. plt.polar([3, 4], [.3, .4])
  522. assert len(fig.axes) == 1, 'More than one polar axes created.'
  523. @check_figures_equal()
  524. def test_polar_wrap(fig_test, fig_ref):
  525. ax = fig_test.add_subplot(projection="polar")
  526. ax.plot(np.deg2rad([179, -179]), [0.2, 0.1])
  527. ax.plot(np.deg2rad([2, -2]), [0.2, 0.1])
  528. ax = fig_ref.add_subplot(projection="polar")
  529. ax.plot(np.deg2rad([179, 181]), [0.2, 0.1])
  530. ax.plot(np.deg2rad([2, 358]), [0.2, 0.1])
  531. @check_figures_equal()
  532. def test_polar_units_1(fig_test, fig_ref):
  533. import matplotlib.testing.jpl_units as units
  534. units.register()
  535. xs = [30.0, 45.0, 60.0, 90.0]
  536. ys = [1.0, 2.0, 3.0, 4.0]
  537. plt.figure(fig_test.number)
  538. plt.polar([x * units.deg for x in xs], ys)
  539. ax = fig_ref.add_subplot(projection="polar")
  540. ax.plot(np.deg2rad(xs), ys)
  541. ax.set(xlabel="deg")
  542. @check_figures_equal()
  543. def test_polar_units_2(fig_test, fig_ref):
  544. import matplotlib.testing.jpl_units as units
  545. units.register()
  546. xs = [30.0, 45.0, 60.0, 90.0]
  547. xs_deg = [x * units.deg for x in xs]
  548. ys = [1.0, 2.0, 3.0, 4.0]
  549. ys_km = [y * units.km for y in ys]
  550. plt.figure(fig_test.number)
  551. # test {theta,r}units.
  552. plt.polar(xs_deg, ys_km, thetaunits="rad", runits="km")
  553. assert isinstance(plt.gca().get_xaxis().get_major_formatter(),
  554. units.UnitDblFormatter)
  555. ax = fig_ref.add_subplot(projection="polar")
  556. ax.plot(np.deg2rad(xs), ys)
  557. ax.xaxis.set_major_formatter(mticker.FuncFormatter("{:.12}".format))
  558. ax.set(xlabel="rad", ylabel="km")
  559. @image_comparison(['polar_rmin'], style='default')
  560. def test_polar_rmin():
  561. r = np.arange(0, 3.0, 0.01)
  562. theta = 2*np.pi*r
  563. fig = plt.figure()
  564. ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True)
  565. ax.plot(theta, r)
  566. ax.set_rmax(2.0)
  567. ax.set_rmin(0.5)
  568. @image_comparison(['polar_negative_rmin'], style='default')
  569. def test_polar_negative_rmin():
  570. r = np.arange(-3.0, 0.0, 0.01)
  571. theta = 2*np.pi*r
  572. fig = plt.figure()
  573. ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True)
  574. ax.plot(theta, r)
  575. ax.set_rmax(0.0)
  576. ax.set_rmin(-3.0)
  577. @image_comparison(['polar_rorigin'], style='default')
  578. def test_polar_rorigin():
  579. r = np.arange(0, 3.0, 0.01)
  580. theta = 2*np.pi*r
  581. fig = plt.figure()
  582. ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True)
  583. ax.plot(theta, r)
  584. ax.set_rmax(2.0)
  585. ax.set_rmin(0.5)
  586. ax.set_rorigin(0.0)
  587. @image_comparison(['polar_invertedylim.png'], style='default')
  588. def test_polar_invertedylim():
  589. fig = plt.figure()
  590. ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True)
  591. ax.set_ylim(2, 0)
  592. @image_comparison(['polar_invertedylim_rorigin.png'], style='default')
  593. def test_polar_invertedylim_rorigin():
  594. fig = plt.figure()
  595. ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True)
  596. ax.set_ylim(2, 0)
  597. ax.set_rorigin(3)
  598. @image_comparison(['polar_theta_position'], style='default')
  599. def test_polar_theta_position():
  600. r = np.arange(0, 3.0, 0.01)
  601. theta = 2*np.pi*r
  602. fig = plt.figure()
  603. ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True)
  604. ax.plot(theta, r)
  605. ax.set_theta_zero_location("NW", 30)
  606. ax.set_theta_direction('clockwise')
  607. @image_comparison(['polar_rlabel_position'], style='default')
  608. def test_polar_rlabel_position():
  609. fig = plt.figure()
  610. ax = fig.add_subplot(111, projection='polar')
  611. ax.set_rlabel_position(315)
  612. ax.tick_params(rotation='auto')
  613. @image_comparison(['polar_theta_wedge'], style='default')
  614. def test_polar_theta_limits():
  615. r = np.arange(0, 3.0, 0.01)
  616. theta = 2*np.pi*r
  617. theta_mins = np.arange(15.0, 361.0, 90.0)
  618. theta_maxs = np.arange(50.0, 361.0, 90.0)
  619. DIRECTIONS = ('out', 'in', 'inout')
  620. fig, axs = plt.subplots(len(theta_mins), len(theta_maxs),
  621. subplot_kw={'polar': True},
  622. figsize=(8, 6))
  623. for i, start in enumerate(theta_mins):
  624. for j, end in enumerate(theta_maxs):
  625. ax = axs[i, j]
  626. ax.plot(theta, r)
  627. if start < end:
  628. ax.set_thetamin(start)
  629. ax.set_thetamax(end)
  630. else:
  631. # Plot with clockwise orientation instead.
  632. ax.set_thetamin(end)
  633. ax.set_thetamax(start)
  634. ax.set_theta_direction('clockwise')
  635. ax.tick_params(tick1On=True, tick2On=True,
  636. direction=DIRECTIONS[i % len(DIRECTIONS)],
  637. rotation='auto')
  638. ax.yaxis.set_tick_params(label2On=True, rotation='auto')
  639. @check_figures_equal(extensions=["png"])
  640. def test_polar_rlim(fig_test, fig_ref):
  641. ax = fig_test.subplots(subplot_kw={'polar': True})
  642. ax.set_rlim(top=10)
  643. ax.set_rlim(bottom=.5)
  644. ax = fig_ref.subplots(subplot_kw={'polar': True})
  645. ax.set_rmax(10.)
  646. ax.set_rmin(.5)
  647. @check_figures_equal(extensions=["png"])
  648. def test_polar_rlim_bottom(fig_test, fig_ref):
  649. ax = fig_test.subplots(subplot_kw={'polar': True})
  650. ax.set_rlim(bottom=[.5, 10])
  651. ax = fig_ref.subplots(subplot_kw={'polar': True})
  652. ax.set_rmax(10.)
  653. ax.set_rmin(.5)
  654. def test_polar_rlim_zero():
  655. ax = plt.figure().add_subplot(projection='polar')
  656. ax.plot(np.arange(10), np.arange(10) + .01)
  657. assert ax.get_ylim()[0] == 0
  658. @image_comparison(['aitoff_proj'], extensions=["png"],
  659. remove_text=True, style='mpl20')
  660. def test_aitoff_proj():
  661. """
  662. Test aitoff projection ref.:
  663. https://github.com/matplotlib/matplotlib/pull/14451
  664. """
  665. x = np.linspace(-np.pi, np.pi, 20)
  666. y = np.linspace(-np.pi / 2, np.pi / 2, 20)
  667. X, Y = np.meshgrid(x, y)
  668. fig, ax = plt.subplots(figsize=(8, 4.2),
  669. subplot_kw=dict(projection="aitoff"))
  670. ax.grid()
  671. ax.plot(X.flat, Y.flat, 'o', markersize=4)
  672. @image_comparison(['axvspan_epoch'])
  673. def test_axvspan_epoch():
  674. from datetime import datetime
  675. import matplotlib.testing.jpl_units as units
  676. units.register()
  677. # generate some data
  678. t0 = units.Epoch("ET", dt=datetime(2009, 1, 20))
  679. tf = units.Epoch("ET", dt=datetime(2009, 1, 21))
  680. dt = units.Duration("ET", units.day.convert("sec"))
  681. ax = plt.gca()
  682. plt.axvspan(t0, tf, facecolor="blue", alpha=0.25)
  683. ax.set_xlim(t0 - 5.0*dt, tf + 5.0*dt)
  684. @image_comparison(['axhspan_epoch'])
  685. def test_axhspan_epoch():
  686. from datetime import datetime
  687. import matplotlib.testing.jpl_units as units
  688. units.register()
  689. # generate some data
  690. t0 = units.Epoch("ET", dt=datetime(2009, 1, 20))
  691. tf = units.Epoch("ET", dt=datetime(2009, 1, 21))
  692. dt = units.Duration("ET", units.day.convert("sec"))
  693. ax = plt.gca()
  694. ax.axhspan(t0, tf, facecolor="blue", alpha=0.25)
  695. ax.set_ylim(t0 - 5.0*dt, tf + 5.0*dt)
  696. @image_comparison(['hexbin_extent.png', 'hexbin_extent.png'], remove_text=True)
  697. def test_hexbin_extent():
  698. # this test exposes sf bug 2856228
  699. fig, ax = plt.subplots()
  700. data = (np.arange(2000) / 2000).reshape((2, 1000))
  701. x, y = data
  702. ax.hexbin(x, y, extent=[.1, .3, .6, .7])
  703. # Reuse testcase from above for a labeled data test
  704. data = {"x": x, "y": y}
  705. fig, ax = plt.subplots()
  706. ax.hexbin("x", "y", extent=[.1, .3, .6, .7], data=data)
  707. @image_comparison(['hexbin_empty.png'], remove_text=True)
  708. def test_hexbin_empty():
  709. # From #3886: creating hexbin from empty dataset raises ValueError
  710. ax = plt.gca()
  711. ax.hexbin([], [])
  712. def test_hexbin_pickable():
  713. # From #1973: Test that picking a hexbin collection works
  714. class FauxMouseEvent:
  715. def __init__(self, x, y):
  716. self.x = x
  717. self.y = y
  718. fig, ax = plt.subplots()
  719. data = (np.arange(200) / 200).reshape((2, 100))
  720. x, y = data
  721. hb = ax.hexbin(x, y, extent=[.1, .3, .6, .7], picker=-1)
  722. assert hb.contains(FauxMouseEvent(400, 300))[0]
  723. @image_comparison(['hexbin_log.png'], style='mpl20')
  724. def test_hexbin_log():
  725. # Issue #1636 (and also test log scaled colorbar)
  726. np.random.seed(19680801)
  727. n = 100000
  728. x = np.random.standard_normal(n)
  729. y = 2.0 + 3.0 * x + 4.0 * np.random.standard_normal(n)
  730. y = np.power(2, y * 0.5)
  731. fig, ax = plt.subplots()
  732. h = ax.hexbin(x, y, yscale='log', bins='log')
  733. plt.colorbar(h)
  734. def test_inverted_limits():
  735. # Test gh:1553
  736. # Calling invert_xaxis prior to plotting should not disable autoscaling
  737. # while still maintaining the inverted direction
  738. fig, ax = plt.subplots()
  739. ax.invert_xaxis()
  740. ax.plot([-5, -3, 2, 4], [1, 2, -3, 5])
  741. assert ax.get_xlim() == (4, -5)
  742. assert ax.get_ylim() == (-3, 5)
  743. plt.close()
  744. fig, ax = plt.subplots()
  745. ax.invert_yaxis()
  746. ax.plot([-5, -3, 2, 4], [1, 2, -3, 5])
  747. assert ax.get_xlim() == (-5, 4)
  748. assert ax.get_ylim() == (5, -3)
  749. # Test inverting nonlinear axes.
  750. fig, ax = plt.subplots()
  751. ax.set_yscale("log")
  752. ax.set_ylim(10, 1)
  753. assert ax.get_ylim() == (10, 1)
  754. @image_comparison(['nonfinite_limits'])
  755. def test_nonfinite_limits():
  756. x = np.arange(0., np.e, 0.01)
  757. # silence divide by zero warning from log(0)
  758. with np.errstate(divide='ignore'):
  759. y = np.log(x)
  760. x[len(x)//2] = np.nan
  761. fig, ax = plt.subplots()
  762. ax.plot(x, y)
  763. @image_comparison(['imshow', 'imshow'], remove_text=True, style='mpl20')
  764. def test_imshow():
  765. # use former defaults to match existing baseline image
  766. matplotlib.rcParams['image.interpolation'] = 'nearest'
  767. # Create a NxN image
  768. N = 100
  769. (x, y) = np.indices((N, N))
  770. x -= N//2
  771. y -= N//2
  772. r = np.sqrt(x**2+y**2-x*y)
  773. # Create a contour plot at N/4 and extract both the clip path and transform
  774. fig, ax = plt.subplots()
  775. ax.imshow(r)
  776. # Reuse testcase from above for a labeled data test
  777. data = {"r": r}
  778. fig = plt.figure()
  779. ax = fig.add_subplot(111)
  780. ax.imshow("r", data=data)
  781. @image_comparison(['imshow_clip'], style='mpl20')
  782. def test_imshow_clip():
  783. # As originally reported by Gellule Xg <gellule.xg@free.fr>
  784. # use former defaults to match existing baseline image
  785. matplotlib.rcParams['image.interpolation'] = 'nearest'
  786. # Create a NxN image
  787. N = 100
  788. (x, y) = np.indices((N, N))
  789. x -= N//2
  790. y -= N//2
  791. r = np.sqrt(x**2+y**2-x*y)
  792. # Create a contour plot at N/4 and extract both the clip path and transform
  793. fig, ax = plt.subplots()
  794. c = ax.contour(r, [N/4])
  795. x = c.collections[0]
  796. clipPath = x.get_paths()[0]
  797. clipTransform = x.get_transform()
  798. from matplotlib.transforms import TransformedPath
  799. clip_path = TransformedPath(clipPath, clipTransform)
  800. # Plot the image clipped by the contour
  801. ax.imshow(r, clip_path=clip_path)
  802. @image_comparison(['polycollection_joinstyle'], remove_text=True)
  803. def test_polycollection_joinstyle():
  804. # Bug #2890979 reported by Matthew West
  805. from matplotlib import collections as mcoll
  806. fig, ax = plt.subplots()
  807. verts = np.array([[1, 1], [1, 2], [2, 2], [2, 1]])
  808. c = mcoll.PolyCollection([verts], linewidths=40)
  809. ax.add_collection(c)
  810. ax.set_xbound(0, 3)
  811. ax.set_ybound(0, 3)
  812. @pytest.mark.parametrize(
  813. 'x, y1, y2', [
  814. (np.zeros((2, 2)), 3, 3),
  815. (np.arange(0.0, 2, 0.02), np.zeros((2, 2)), 3),
  816. (np.arange(0.0, 2, 0.02), 3, np.zeros((2, 2)))
  817. ], ids=[
  818. '2d_x_input',
  819. '2d_y1_input',
  820. '2d_y2_input'
  821. ]
  822. )
  823. def test_fill_between_input(x, y1, y2):
  824. fig, ax = plt.subplots()
  825. with pytest.raises(ValueError):
  826. ax.fill_between(x, y1, y2)
  827. @pytest.mark.parametrize(
  828. 'y, x1, x2', [
  829. (np.zeros((2, 2)), 3, 3),
  830. (np.arange(0.0, 2, 0.02), np.zeros((2, 2)), 3),
  831. (np.arange(0.0, 2, 0.02), 3, np.zeros((2, 2)))
  832. ], ids=[
  833. '2d_y_input',
  834. '2d_x1_input',
  835. '2d_x2_input'
  836. ]
  837. )
  838. def test_fill_betweenx_input(y, x1, x2):
  839. fig, ax = plt.subplots()
  840. with pytest.raises(ValueError):
  841. ax.fill_betweenx(y, x1, x2)
  842. @image_comparison(['fill_between_interpolate'], remove_text=True)
  843. def test_fill_between_interpolate():
  844. x = np.arange(0.0, 2, 0.02)
  845. y1 = np.sin(2*np.pi*x)
  846. y2 = 1.2*np.sin(4*np.pi*x)
  847. fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)
  848. ax1.plot(x, y1, x, y2, color='black')
  849. ax1.fill_between(x, y1, y2, where=y2 >= y1, facecolor='white', hatch='/',
  850. interpolate=True)
  851. ax1.fill_between(x, y1, y2, where=y2 <= y1, facecolor='red',
  852. interpolate=True)
  853. # Test support for masked arrays.
  854. y2 = np.ma.masked_greater(y2, 1.0)
  855. # Test that plotting works for masked arrays with the first element masked
  856. y2[0] = np.ma.masked
  857. ax2.plot(x, y1, x, y2, color='black')
  858. ax2.fill_between(x, y1, y2, where=y2 >= y1, facecolor='green',
  859. interpolate=True)
  860. ax2.fill_between(x, y1, y2, where=y2 <= y1, facecolor='red',
  861. interpolate=True)
  862. @image_comparison(['fill_between_interpolate_decreasing'],
  863. style='mpl20', remove_text=True)
  864. def test_fill_between_interpolate_decreasing():
  865. p = np.array([724.3, 700, 655])
  866. t = np.array([9.4, 7, 2.2])
  867. prof = np.array([7.9, 6.6, 3.8])
  868. fig, ax = plt.subplots(figsize=(9, 9))
  869. ax.plot(t, p, 'tab:red')
  870. ax.plot(prof, p, 'k')
  871. ax.fill_betweenx(p, t, prof, where=prof < t,
  872. facecolor='blue', interpolate=True, alpha=0.4)
  873. ax.fill_betweenx(p, t, prof, where=prof > t,
  874. facecolor='red', interpolate=True, alpha=0.4)
  875. ax.set_xlim(0, 30)
  876. ax.set_ylim(800, 600)
  877. # test_symlog and test_symlog2 used to have baseline images in all three
  878. # formats, but the png and svg baselines got invalidated by the removal of
  879. # minor tick overstriking.
  880. @image_comparison(['symlog.pdf'])
  881. def test_symlog():
  882. x = np.array([0, 1, 2, 4, 6, 9, 12, 24])
  883. y = np.array([1000000, 500000, 100000, 100, 5, 0, 0, 0])
  884. fig, ax = plt.subplots()
  885. ax.plot(x, y)
  886. ax.set_yscale('symlog')
  887. ax.set_xscale('linear')
  888. ax.set_ylim(-1, 10000000)
  889. @image_comparison(['symlog2.pdf'], remove_text=True)
  890. def test_symlog2():
  891. # Numbers from -50 to 50, with 0.1 as step
  892. x = np.arange(-50, 50, 0.001)
  893. fig, axs = plt.subplots(5, 1)
  894. for ax, linthreshx in zip(axs, [20., 2., 1., 0.1, 0.01]):
  895. ax.plot(x, x)
  896. ax.set_xscale('symlog', linthreshx=linthreshx)
  897. ax.grid(True)
  898. axs[-1].set_ylim(-0.1, 0.1)
  899. def test_pcolorargs_5205():
  900. # Smoketest to catch issue found in gh:5205
  901. x = [-1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5]
  902. y = [-1.5, -1.25, -1.0, -0.75, -0.5, -0.25, 0,
  903. 0.25, 0.5, 0.75, 1.0, 1.25, 1.5]
  904. X, Y = np.meshgrid(x, y)
  905. Z = np.hypot(X, Y)
  906. plt.pcolor(Z)
  907. plt.pcolor(list(Z))
  908. plt.pcolor(x, y, Z)
  909. plt.pcolor(X, Y, list(Z))
  910. @image_comparison(['pcolormesh'], remove_text=True)
  911. def test_pcolormesh():
  912. n = 12
  913. x = np.linspace(-1.5, 1.5, n)
  914. y = np.linspace(-1.5, 1.5, n*2)
  915. X, Y = np.meshgrid(x, y)
  916. Qx = np.cos(Y) - np.cos(X)
  917. Qz = np.sin(Y) + np.sin(X)
  918. Qx = (Qx + 1.1)
  919. Z = np.hypot(X, Y) / 5
  920. Z = (Z - Z.min()) / Z.ptp()
  921. # The color array can include masked values:
  922. Zm = ma.masked_where(np.abs(Qz) < 0.5 * np.max(Qz), Z)
  923. fig, (ax1, ax2, ax3) = plt.subplots(1, 3)
  924. ax1.pcolormesh(Qx, Qz, Z, lw=0.5, edgecolors='k')
  925. ax2.pcolormesh(Qx, Qz, Z, lw=2, edgecolors=['b', 'w'])
  926. ax3.pcolormesh(Qx, Qz, Z, shading="gouraud")
  927. @image_comparison(['pcolormesh_alpha'], extensions=["png", "pdf"],
  928. remove_text=True)
  929. def test_pcolormesh_alpha():
  930. n = 12
  931. X, Y = np.meshgrid(
  932. np.linspace(-1.5, 1.5, n),
  933. np.linspace(-1.5, 1.5, n*2)
  934. )
  935. Qx = X
  936. Qy = Y + np.sin(X)
  937. Z = np.hypot(X, Y) / 5
  938. Z = (Z - Z.min()) / Z.ptp()
  939. vir = plt.get_cmap("viridis", 16)
  940. # make another colormap with varying alpha
  941. colors = vir(np.arange(16))
  942. colors[:, 3] = 0.5 + 0.5*np.sin(np.arange(16))
  943. cmap = mcolors.ListedColormap(colors)
  944. fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)
  945. for ax in ax1, ax2, ax3, ax4:
  946. ax.add_patch(mpatches.Rectangle(
  947. (0, -1.5), 1.5, 3, facecolor=[.7, .1, .1, .5], zorder=0
  948. ))
  949. # ax1, ax2: constant alpha
  950. ax1.pcolormesh(Qx, Qy, Z, cmap=vir, alpha=0.4, shading='flat', zorder=1)
  951. ax2.pcolormesh(Qx, Qy, Z, cmap=vir, alpha=0.4, shading='gouraud', zorder=1)
  952. # ax3, ax4: alpha from colormap
  953. ax3.pcolormesh(Qx, Qy, Z, cmap=cmap, shading='flat', zorder=1)
  954. ax4.pcolormesh(Qx, Qy, Z, cmap=cmap, shading='gouraud', zorder=1)
  955. @image_comparison(['pcolormesh_datetime_axis.png'],
  956. remove_text=False, style='mpl20')
  957. def test_pcolormesh_datetime_axis():
  958. fig = plt.figure()
  959. fig.subplots_adjust(hspace=0.4, top=0.98, bottom=.15)
  960. base = datetime.datetime(2013, 1, 1)
  961. x = np.array([base + datetime.timedelta(days=d) for d in range(21)])
  962. y = np.arange(21)
  963. z1, z2 = np.meshgrid(np.arange(20), np.arange(20))
  964. z = z1 * z2
  965. plt.subplot(221)
  966. plt.pcolormesh(x[:-1], y[:-1], z)
  967. plt.subplot(222)
  968. plt.pcolormesh(x, y, z)
  969. x = np.repeat(x[np.newaxis], 21, axis=0)
  970. y = np.repeat(y[:, np.newaxis], 21, axis=1)
  971. plt.subplot(223)
  972. plt.pcolormesh(x[:-1, :-1], y[:-1, :-1], z)
  973. plt.subplot(224)
  974. plt.pcolormesh(x, y, z)
  975. for ax in fig.get_axes():
  976. for label in ax.get_xticklabels():
  977. label.set_ha('right')
  978. label.set_rotation(30)
  979. @image_comparison(['pcolor_datetime_axis.png'],
  980. remove_text=False, style='mpl20')
  981. def test_pcolor_datetime_axis():
  982. fig = plt.figure()
  983. fig.subplots_adjust(hspace=0.4, top=0.98, bottom=.15)
  984. base = datetime.datetime(2013, 1, 1)
  985. x = np.array([base + datetime.timedelta(days=d) for d in range(21)])
  986. y = np.arange(21)
  987. z1, z2 = np.meshgrid(np.arange(20), np.arange(20))
  988. z = z1 * z2
  989. plt.subplot(221)
  990. plt.pcolor(x[:-1], y[:-1], z)
  991. plt.subplot(222)
  992. plt.pcolor(x, y, z)
  993. x = np.repeat(x[np.newaxis], 21, axis=0)
  994. y = np.repeat(y[:, np.newaxis], 21, axis=1)
  995. plt.subplot(223)
  996. plt.pcolor(x[:-1, :-1], y[:-1, :-1], z)
  997. plt.subplot(224)
  998. plt.pcolor(x, y, z)
  999. for ax in fig.get_axes():
  1000. for label in ax.get_xticklabels():
  1001. label.set_ha('right')
  1002. label.set_rotation(30)
  1003. def test_pcolorargs():
  1004. n = 12
  1005. x = np.linspace(-1.5, 1.5, n)
  1006. y = np.linspace(-1.5, 1.5, n*2)
  1007. X, Y = np.meshgrid(x, y)
  1008. Z = np.hypot(X, Y) / 5
  1009. _, ax = plt.subplots()
  1010. with pytest.raises(TypeError):
  1011. ax.pcolormesh(y, x, Z)
  1012. with pytest.raises(TypeError):
  1013. ax.pcolormesh(X, Y, Z.T)
  1014. with pytest.raises(TypeError):
  1015. ax.pcolormesh(x, y, Z[:-1, :-1], shading="gouraud")
  1016. with pytest.raises(TypeError):
  1017. ax.pcolormesh(X, Y, Z[:-1, :-1], shading="gouraud")
  1018. x[0] = np.NaN
  1019. with pytest.raises(ValueError):
  1020. ax.pcolormesh(x, y, Z[:-1, :-1])
  1021. with np.errstate(invalid='ignore'):
  1022. x = np.ma.array(x, mask=(x < 0))
  1023. with pytest.raises(ValueError):
  1024. ax.pcolormesh(x, y, Z[:-1, :-1])
  1025. @image_comparison(['canonical'])
  1026. def test_canonical():
  1027. fig, ax = plt.subplots()
  1028. ax.plot([1, 2, 3])
  1029. @image_comparison(['arc_angles.png'], remove_text=True, style='default')
  1030. def test_arc_angles():
  1031. from matplotlib import patches
  1032. # Ellipse parameters
  1033. w = 2
  1034. h = 1
  1035. centre = (0.2, 0.5)
  1036. scale = 2
  1037. fig, axs = plt.subplots(3, 3)
  1038. for i, ax in enumerate(axs.flat):
  1039. theta2 = i * 360 / 9
  1040. theta1 = theta2 - 45
  1041. ax.add_patch(patches.Ellipse(centre, w, h, alpha=0.3))
  1042. ax.add_patch(patches.Arc(centre, w, h, theta1=theta1, theta2=theta2))
  1043. # Straight lines intersecting start and end of arc
  1044. ax.plot([scale * np.cos(np.deg2rad(theta1)) + centre[0],
  1045. centre[0],
  1046. scale * np.cos(np.deg2rad(theta2)) + centre[0]],
  1047. [scale * np.sin(np.deg2rad(theta1)) + centre[1],
  1048. centre[1],
  1049. scale * np.sin(np.deg2rad(theta2)) + centre[1]])
  1050. ax.set_xlim(-scale, scale)
  1051. ax.set_ylim(-scale, scale)
  1052. # This looks the same, but it triggers a different code path when it
  1053. # gets large enough.
  1054. w *= 10
  1055. h *= 10
  1056. centre = (centre[0] * 10, centre[1] * 10)
  1057. scale *= 10
  1058. @image_comparison(['arc_ellipse'], remove_text=True)
  1059. def test_arc_ellipse():
  1060. from matplotlib import patches
  1061. xcenter, ycenter = 0.38, 0.52
  1062. width, height = 1e-1, 3e-1
  1063. angle = -30
  1064. theta = np.deg2rad(np.arange(360))
  1065. x = width / 2. * np.cos(theta)
  1066. y = height / 2. * np.sin(theta)
  1067. rtheta = np.deg2rad(angle)
  1068. R = np.array([
  1069. [np.cos(rtheta), -np.sin(rtheta)],
  1070. [np.sin(rtheta), np.cos(rtheta)]])
  1071. x, y = np.dot(R, np.array([x, y]))
  1072. x += xcenter
  1073. y += ycenter
  1074. fig = plt.figure()
  1075. ax = fig.add_subplot(211, aspect='auto')
  1076. ax.fill(x, y, alpha=0.2, facecolor='yellow', edgecolor='yellow',
  1077. linewidth=1, zorder=1)
  1078. e1 = patches.Arc((xcenter, ycenter), width, height,
  1079. angle=angle, linewidth=2, fill=False, zorder=2)
  1080. ax.add_patch(e1)
  1081. ax = fig.add_subplot(212, aspect='equal')
  1082. ax.fill(x, y, alpha=0.2, facecolor='green', edgecolor='green', zorder=1)
  1083. e2 = patches.Arc((xcenter, ycenter), width, height,
  1084. angle=angle, linewidth=2, fill=False, zorder=2)
  1085. ax.add_patch(e2)
  1086. @image_comparison(['markevery'], remove_text=True)
  1087. def test_markevery():
  1088. x = np.linspace(0, 10, 100)
  1089. y = np.sin(x) * np.sqrt(x/10 + 0.5)
  1090. # check marker only plot
  1091. fig = plt.figure()
  1092. ax = fig.add_subplot(111)
  1093. ax.plot(x, y, 'o', label='default')
  1094. ax.plot(x, y, 'd', markevery=None, label='mark all')
  1095. ax.plot(x, y, 's', markevery=10, label='mark every 10')
  1096. ax.plot(x, y, '+', markevery=(5, 20), label='mark every 5 starting at 10')
  1097. ax.legend()
  1098. @image_comparison(['markevery_line'], remove_text=True)
  1099. def test_markevery_line():
  1100. x = np.linspace(0, 10, 100)
  1101. y = np.sin(x) * np.sqrt(x/10 + 0.5)
  1102. # check line/marker combos
  1103. fig = plt.figure()
  1104. ax = fig.add_subplot(111)
  1105. ax.plot(x, y, '-o', label='default')
  1106. ax.plot(x, y, '-d', markevery=None, label='mark all')
  1107. ax.plot(x, y, '-s', markevery=10, label='mark every 10')
  1108. ax.plot(x, y, '-+', markevery=(5, 20), label='mark every 5 starting at 10')
  1109. ax.legend()
  1110. @image_comparison(['markevery_linear_scales'], remove_text=True)
  1111. def test_markevery_linear_scales():
  1112. cases = [None,
  1113. 8,
  1114. (30, 8),
  1115. [16, 24, 30], [0, -1],
  1116. slice(100, 200, 3),
  1117. 0.1, 0.3, 1.5,
  1118. (0.0, 0.1), (0.45, 0.1)]
  1119. cols = 3
  1120. gs = matplotlib.gridspec.GridSpec(len(cases) // cols + 1, cols)
  1121. delta = 0.11
  1122. x = np.linspace(0, 10 - 2 * delta, 200) + delta
  1123. y = np.sin(x) + 1.0 + delta
  1124. for i, case in enumerate(cases):
  1125. row = (i // cols)
  1126. col = i % cols
  1127. plt.subplot(gs[row, col])
  1128. plt.title('markevery=%s' % str(case))
  1129. plt.plot(x, y, 'o', ls='-', ms=4, markevery=case)
  1130. @image_comparison(['markevery_linear_scales_zoomed'], remove_text=True)
  1131. def test_markevery_linear_scales_zoomed():
  1132. cases = [None,
  1133. 8,
  1134. (30, 8),
  1135. [16, 24, 30], [0, -1],
  1136. slice(100, 200, 3),
  1137. 0.1, 0.3, 1.5,
  1138. (0.0, 0.1), (0.45, 0.1)]
  1139. cols = 3
  1140. gs = matplotlib.gridspec.GridSpec(len(cases) // cols + 1, cols)
  1141. delta = 0.11
  1142. x = np.linspace(0, 10 - 2 * delta, 200) + delta
  1143. y = np.sin(x) + 1.0 + delta
  1144. for i, case in enumerate(cases):
  1145. row = (i // cols)
  1146. col = i % cols
  1147. plt.subplot(gs[row, col])
  1148. plt.title('markevery=%s' % str(case))
  1149. plt.plot(x, y, 'o', ls='-', ms=4, markevery=case)
  1150. plt.xlim((6, 6.7))
  1151. plt.ylim((1.1, 1.7))
  1152. @image_comparison(['markevery_log_scales'], remove_text=True)
  1153. def test_markevery_log_scales():
  1154. cases = [None,
  1155. 8,
  1156. (30, 8),
  1157. [16, 24, 30], [0, -1],
  1158. slice(100, 200, 3),
  1159. 0.1, 0.3, 1.5,
  1160. (0.0, 0.1), (0.45, 0.1)]
  1161. cols = 3
  1162. gs = matplotlib.gridspec.GridSpec(len(cases) // cols + 1, cols)
  1163. delta = 0.11
  1164. x = np.linspace(0, 10 - 2 * delta, 200) + delta
  1165. y = np.sin(x) + 1.0 + delta
  1166. for i, case in enumerate(cases):
  1167. row = (i // cols)
  1168. col = i % cols
  1169. plt.subplot(gs[row, col])
  1170. plt.title('markevery=%s' % str(case))
  1171. plt.xscale('log')
  1172. plt.yscale('log')
  1173. plt.plot(x, y, 'o', ls='-', ms=4, markevery=case)
  1174. @image_comparison(['markevery_polar'], style='default', remove_text=True)
  1175. def test_markevery_polar():
  1176. cases = [None,
  1177. 8,
  1178. (30, 8),
  1179. [16, 24, 30], [0, -1],
  1180. slice(100, 200, 3),
  1181. 0.1, 0.3, 1.5,
  1182. (0.0, 0.1), (0.45, 0.1)]
  1183. cols = 3
  1184. gs = matplotlib.gridspec.GridSpec(len(cases) // cols + 1, cols)
  1185. r = np.linspace(0, 3.0, 200)
  1186. theta = 2 * np.pi * r
  1187. for i, case in enumerate(cases):
  1188. row = (i // cols)
  1189. col = i % cols
  1190. plt.subplot(gs[row, col], polar=True)
  1191. plt.title('markevery=%s' % str(case))
  1192. plt.plot(theta, r, 'o', ls='-', ms=4, markevery=case)
  1193. @image_comparison(['marker_edges'], remove_text=True)
  1194. def test_marker_edges():
  1195. x = np.linspace(0, 1, 10)
  1196. fig = plt.figure()
  1197. ax = fig.add_subplot(111)
  1198. ax.plot(x, np.sin(x), 'y.', ms=30.0, mew=0, mec='r')
  1199. ax.plot(x+0.1, np.sin(x), 'y.', ms=30.0, mew=1, mec='r')
  1200. ax.plot(x+0.2, np.sin(x), 'y.', ms=30.0, mew=2, mec='b')
  1201. @image_comparison(['bar_tick_label_single.png', 'bar_tick_label_single.png'])
  1202. def test_bar_tick_label_single():
  1203. # From 2516: plot bar with array of string labels for x axis
  1204. ax = plt.gca()
  1205. ax.bar(0, 1, align='edge', tick_label='0')
  1206. # Reuse testcase from above for a labeled data test
  1207. data = {"a": 0, "b": 1}
  1208. fig = plt.figure()
  1209. ax = fig.add_subplot(111)
  1210. ax = plt.gca()
  1211. ax.bar("a", "b", align='edge', tick_label='0', data=data)
  1212. def test_bar_ticklabel_fail():
  1213. fig, ax = plt.subplots()
  1214. ax.bar([], [])
  1215. @image_comparison(['bar_tick_label_multiple.png'])
  1216. def test_bar_tick_label_multiple():
  1217. # From 2516: plot bar with array of string labels for x axis
  1218. ax = plt.gca()
  1219. ax.bar([1, 2.5], [1, 2], width=[0.2, 0.5], tick_label=['a', 'b'],
  1220. align='center')
  1221. @image_comparison(['bar_tick_label_multiple_old_label_alignment.png'])
  1222. def test_bar_tick_label_multiple_old_alignment():
  1223. # Test that the alignment for class is backward compatible
  1224. matplotlib.rcParams["ytick.alignment"] = "center"
  1225. ax = plt.gca()
  1226. ax.bar([1, 2.5], [1, 2], width=[0.2, 0.5], tick_label=['a', 'b'],
  1227. align='center')
  1228. @check_figures_equal(extensions=["png"])
  1229. def test_bar_decimal_center(fig_test, fig_ref):
  1230. ax = fig_test.subplots()
  1231. x0 = [1.5, 8.4, 5.3, 4.2]
  1232. y0 = [1.1, 2.2, 3.3, 4.4]
  1233. x = [Decimal(x) for x in x0]
  1234. y = [Decimal(y) for y in y0]
  1235. # Test image - vertical, align-center bar chart with Decimal() input
  1236. ax.bar(x, y, align='center')
  1237. # Reference image
  1238. ax = fig_ref.subplots()
  1239. ax.bar(x0, y0, align='center')
  1240. @check_figures_equal(extensions=["png"])
  1241. def test_barh_decimal_center(fig_test, fig_ref):
  1242. ax = fig_test.subplots()
  1243. x0 = [1.5, 8.4, 5.3, 4.2]
  1244. y0 = [1.1, 2.2, 3.3, 4.4]
  1245. x = [Decimal(x) for x in x0]
  1246. y = [Decimal(y) for y in y0]
  1247. # Test image - horizontal, align-center bar chart with Decimal() input
  1248. ax.barh(x, y, height=[0.5, 0.5, 1, 1], align='center')
  1249. # Reference image
  1250. ax = fig_ref.subplots()
  1251. ax.barh(x0, y0, height=[0.5, 0.5, 1, 1], align='center')
  1252. @check_figures_equal(extensions=["png"])
  1253. def test_bar_decimal_width(fig_test, fig_ref):
  1254. x = [1.5, 8.4, 5.3, 4.2]
  1255. y = [1.1, 2.2, 3.3, 4.4]
  1256. w0 = [0.7, 1.45, 1, 2]
  1257. w = [Decimal(i) for i in w0]
  1258. # Test image - vertical bar chart with Decimal() width
  1259. ax = fig_test.subplots()
  1260. ax.bar(x, y, width=w, align='center')
  1261. # Reference image
  1262. ax = fig_ref.subplots()
  1263. ax.bar(x, y, width=w0, align='center')
  1264. @check_figures_equal(extensions=["png"])
  1265. def test_barh_decimal_height(fig_test, fig_ref):
  1266. x = [1.5, 8.4, 5.3, 4.2]
  1267. y = [1.1, 2.2, 3.3, 4.4]
  1268. h0 = [0.7, 1.45, 1, 2]
  1269. h = [Decimal(i) for i in h0]
  1270. # Test image - horizontal bar chart with Decimal() height
  1271. ax = fig_test.subplots()
  1272. ax.barh(x, y, height=h, align='center')
  1273. # Reference image
  1274. ax = fig_ref.subplots()
  1275. ax.barh(x, y, height=h0, align='center')
  1276. def test_bar_color_none_alpha():
  1277. ax = plt.gca()
  1278. rects = ax.bar([1, 2], [2, 4], alpha=0.3, color='none', edgecolor='r')
  1279. for rect in rects:
  1280. assert rect.get_facecolor() == (0, 0, 0, 0)
  1281. assert rect.get_edgecolor() == (1, 0, 0, 0.3)
  1282. def test_bar_edgecolor_none_alpha():
  1283. ax = plt.gca()
  1284. rects = ax.bar([1, 2], [2, 4], alpha=0.3, color='r', edgecolor='none')
  1285. for rect in rects:
  1286. assert rect.get_facecolor() == (1, 0, 0, 0.3)
  1287. assert rect.get_edgecolor() == (0, 0, 0, 0)
  1288. @image_comparison(['barh_tick_label.png'])
  1289. def test_barh_tick_label():
  1290. # From 2516: plot barh with array of string labels for y axis
  1291. ax = plt.gca()
  1292. ax.barh([1, 2.5], [1, 2], height=[0.2, 0.5], tick_label=['a', 'b'],
  1293. align='center')
  1294. def test_bar_timedelta():
  1295. """smoketest that bar can handle width and height in delta units"""
  1296. fig, ax = plt.subplots()
  1297. ax.bar(datetime.datetime(2018, 1, 1), 1.,
  1298. width=datetime.timedelta(hours=3))
  1299. ax.bar(datetime.datetime(2018, 1, 1), 1.,
  1300. xerr=datetime.timedelta(hours=2),
  1301. width=datetime.timedelta(hours=3))
  1302. fig, ax = plt.subplots()
  1303. ax.barh(datetime.datetime(2018, 1, 1), 1,
  1304. height=datetime.timedelta(hours=3))
  1305. ax.barh(datetime.datetime(2018, 1, 1), 1,
  1306. height=datetime.timedelta(hours=3),
  1307. yerr=datetime.timedelta(hours=2))
  1308. fig, ax = plt.subplots()
  1309. ax.barh([datetime.datetime(2018, 1, 1), datetime.datetime(2018, 1, 1)],
  1310. np.array([1, 1.5]),
  1311. height=datetime.timedelta(hours=3))
  1312. ax.barh([datetime.datetime(2018, 1, 1), datetime.datetime(2018, 1, 1)],
  1313. np.array([1, 1.5]),
  1314. height=[datetime.timedelta(hours=t) for t in [1, 2]])
  1315. ax.broken_barh([(datetime.datetime(2018, 1, 1),
  1316. datetime.timedelta(hours=1))],
  1317. (10, 20))
  1318. def test_boxplot_dates_pandas(pd):
  1319. # smoke test for boxplot and dates in pandas
  1320. data = np.random.rand(5, 2)
  1321. years = pd.date_range('1/1/2000',
  1322. periods=2, freq=pd.DateOffset(years=1)).year
  1323. plt.figure()
  1324. plt.boxplot(data, positions=years)
  1325. def test_bar_pandas(pd):
  1326. # Smoke test for pandas
  1327. df = pd.DataFrame(
  1328. {'year': [2018, 2018, 2018],
  1329. 'month': [1, 1, 1],
  1330. 'day': [1, 2, 3],
  1331. 'value': [1, 2, 3]})
  1332. df['date'] = pd.to_datetime(df[['year', 'month', 'day']])
  1333. monthly = df[['date', 'value']].groupby(['date']).sum()
  1334. dates = monthly.index
  1335. forecast = monthly['value']
  1336. baseline = monthly['value']
  1337. fig, ax = plt.subplots()
  1338. ax.bar(dates, forecast, width=10, align='center')
  1339. ax.plot(dates, baseline, color='orange', lw=4)
  1340. def test_bar_pandas_indexed(pd):
  1341. # Smoke test for indexed pandas
  1342. df = pd.DataFrame({"x": [1., 2., 3.], "width": [.2, .4, .6]},
  1343. index=[1, 2, 3])
  1344. fig, ax = plt.subplots()
  1345. ax.bar(df.x, 1., width=df.width)
  1346. def test_pandas_minimal_plot(pd):
  1347. # smoke test that series and index objcets do not warn
  1348. x = pd.Series([1, 2], dtype="float64")
  1349. plt.plot(x, x)
  1350. plt.plot(x.index, x)
  1351. plt.plot(x)
  1352. plt.plot(x.index)
  1353. @image_comparison(['hist_log'], remove_text=True)
  1354. def test_hist_log():
  1355. data0 = np.linspace(0, 1, 200)**3
  1356. data = np.r_[1-data0, 1+data0]
  1357. fig = plt.figure()
  1358. ax = fig.add_subplot(111)
  1359. ax.hist(data, fill=False, log=True)
  1360. @check_figures_equal(extensions=["png"])
  1361. def test_hist_log_2(fig_test, fig_ref):
  1362. axs_test = fig_test.subplots(2, 3)
  1363. axs_ref = fig_ref.subplots(2, 3)
  1364. for i, histtype in enumerate(["bar", "step", "stepfilled"]):
  1365. # Set log scale, then call hist().
  1366. axs_test[0, i].set_yscale("log")
  1367. axs_test[0, i].hist(1, 1, histtype=histtype)
  1368. # Call hist(), then set log scale.
  1369. axs_test[1, i].hist(1, 1, histtype=histtype)
  1370. axs_test[1, i].set_yscale("log")
  1371. # Use hist(..., log=True).
  1372. for ax in axs_ref[:, i]:
  1373. ax.hist(1, 1, log=True, histtype=histtype)
  1374. @image_comparison(['hist_bar_empty.png'], remove_text=True)
  1375. def test_hist_bar_empty():
  1376. # From #3886: creating hist from empty dataset raises ValueError
  1377. ax = plt.gca()
  1378. ax.hist([], histtype='bar')
  1379. @image_comparison(['hist_step_empty.png'], remove_text=True)
  1380. def test_hist_step_empty():
  1381. # From #3886: creating hist from empty dataset raises ValueError
  1382. ax = plt.gca()
  1383. ax.hist([], histtype='step')
  1384. @image_comparison(['hist_step_filled.png'], remove_text=True)
  1385. def test_hist_step_filled():
  1386. np.random.seed(0)
  1387. x = np.random.randn(1000, 3)
  1388. n_bins = 10
  1389. kwargs = [{'fill': True}, {'fill': False}, {'fill': None}, {}]*2
  1390. types = ['step']*4+['stepfilled']*4
  1391. fig, axs = plt.subplots(nrows=2, ncols=4)
  1392. for kg, _type, ax in zip(kwargs, types, axs.flat):
  1393. ax.hist(x, n_bins, histtype=_type, stacked=True, **kg)
  1394. ax.set_title('%s/%s' % (kg, _type))
  1395. ax.set_ylim(bottom=-50)
  1396. patches = axs[0, 0].patches
  1397. assert all(p.get_facecolor() == p.get_edgecolor() for p in patches)
  1398. @image_comparison(['hist_density.png'])
  1399. def test_hist_density():
  1400. np.random.seed(19680801)
  1401. data = np.random.standard_normal(2000)
  1402. fig, ax = plt.subplots()
  1403. ax.hist(data, density=True)
  1404. def test_hist_unequal_bins_density():
  1405. # Test correct behavior of normalized histogram with unequal bins
  1406. # https://github.com/matplotlib/matplotlib/issues/9557
  1407. rng = np.random.RandomState(57483)
  1408. t = rng.randn(100)
  1409. bins = [-3, -1, -0.5, 0, 1, 5]
  1410. mpl_heights, _, _ = plt.hist(t, bins=bins, density=True)
  1411. np_heights, _ = np.histogram(t, bins=bins, density=True)
  1412. assert_allclose(mpl_heights, np_heights)
  1413. def test_hist_datetime_datasets():
  1414. data = [[datetime.datetime(2017, 1, 1), datetime.datetime(2017, 1, 1)],
  1415. [datetime.datetime(2017, 1, 1), datetime.datetime(2017, 1, 2)]]
  1416. fig, ax = plt.subplots()
  1417. ax.hist(data, stacked=True)
  1418. ax.hist(data, stacked=False)
  1419. @pytest.mark.parametrize("bins_preprocess",
  1420. [mpl.dates.date2num,
  1421. lambda bins: bins,
  1422. lambda bins: np.asarray(bins).astype('datetime64')],
  1423. ids=['date2num', 'datetime.datetime',
  1424. 'np.datetime64'])
  1425. def test_hist_datetime_datasets_bins(bins_preprocess):
  1426. data = [[datetime.datetime(2019, 1, 5), datetime.datetime(2019, 1, 11),
  1427. datetime.datetime(2019, 2, 1), datetime.datetime(2019, 3, 1)],
  1428. [datetime.datetime(2019, 1, 11), datetime.datetime(2019, 2, 5),
  1429. datetime.datetime(2019, 2, 18), datetime.datetime(2019, 3, 1)]]
  1430. date_edges = [datetime.datetime(2019, 1, 1), datetime.datetime(2019, 2, 1),
  1431. datetime.datetime(2019, 3, 1)]
  1432. fig, ax = plt.subplots()
  1433. _, bins, _ = ax.hist(data, bins=bins_preprocess(date_edges), stacked=True)
  1434. np.testing.assert_allclose(bins, mpl.dates.date2num(date_edges))
  1435. _, bins, _ = ax.hist(data, bins=bins_preprocess(date_edges), stacked=False)
  1436. np.testing.assert_allclose(bins, mpl.dates.date2num(date_edges))
  1437. @pytest.mark.parametrize('data, expected_number_of_hists',
  1438. [([], 1),
  1439. ([[]], 1),
  1440. ([[], []], 2)])
  1441. def test_hist_with_empty_input(data, expected_number_of_hists):
  1442. hists, _, _ = plt.hist(data)
  1443. hists = np.asarray(hists)
  1444. if hists.ndim == 1:
  1445. assert 1 == expected_number_of_hists
  1446. else:
  1447. assert hists.shape[0] == expected_number_of_hists
  1448. def contour_dat():
  1449. x = np.linspace(-3, 5, 150)
  1450. y = np.linspace(-3, 5, 120)
  1451. z = np.cos(x) + np.sin(y[:, np.newaxis])
  1452. return x, y, z
  1453. @image_comparison(['contour_hatching'], remove_text=True, style='mpl20')
  1454. def test_contour_hatching():
  1455. x, y, z = contour_dat()
  1456. fig = plt.figure()
  1457. ax = fig.add_subplot(111)
  1458. ax.contourf(x, y, z, 7, hatches=['/', '\\', '//', '-'],
  1459. cmap=plt.get_cmap('gray'),
  1460. extend='both', alpha=0.5)
  1461. @image_comparison(['contour_colorbar'], style='mpl20')
  1462. def test_contour_colorbar():
  1463. x, y, z = contour_dat()
  1464. fig = plt.figure()
  1465. ax = fig.add_subplot(111)
  1466. cs = ax.contourf(x, y, z, levels=np.arange(-1.8, 1.801, 0.2),
  1467. cmap=plt.get_cmap('RdBu'),
  1468. vmin=-0.6,
  1469. vmax=0.6,
  1470. extend='both')
  1471. cs1 = ax.contour(x, y, z, levels=np.arange(-2.2, -0.599, 0.2),
  1472. colors=['y'],
  1473. linestyles='solid',
  1474. linewidths=2)
  1475. cs2 = ax.contour(x, y, z, levels=np.arange(0.6, 2.2, 0.2),
  1476. colors=['c'],
  1477. linewidths=2)
  1478. cbar = fig.colorbar(cs, ax=ax)
  1479. cbar.add_lines(cs1)
  1480. cbar.add_lines(cs2, erase=False)
  1481. @image_comparison(['hist2d', 'hist2d'], remove_text=True, style='mpl20')
  1482. def test_hist2d():
  1483. np.random.seed(0)
  1484. # make it not symmetric in case we switch x and y axis
  1485. x = np.random.randn(100)*2+5
  1486. y = np.random.randn(100)-2
  1487. fig = plt.figure()
  1488. ax = fig.add_subplot(111)
  1489. ax.hist2d(x, y, bins=10, rasterized=True)
  1490. # Reuse testcase from above for a labeled data test
  1491. data = {"x": x, "y": y}
  1492. fig = plt.figure()
  1493. ax = fig.add_subplot(111)
  1494. ax.hist2d("x", "y", bins=10, data=data, rasterized=True)
  1495. @image_comparison(['hist2d_transpose'], remove_text=True, style='mpl20')
  1496. def test_hist2d_transpose():
  1497. np.random.seed(0)
  1498. # make sure the output from np.histogram is transposed before
  1499. # passing to pcolorfast
  1500. x = np.array([5]*100)
  1501. y = np.random.randn(100)-2
  1502. fig = plt.figure()
  1503. ax = fig.add_subplot(111)
  1504. ax.hist2d(x, y, bins=10, rasterized=True)
  1505. def test_hist2d_density_normed():
  1506. x, y = np.random.random((2, 100))
  1507. ax = plt.figure().subplots()
  1508. for obj in [ax, plt]:
  1509. obj.hist2d(x, y, density=True)
  1510. with pytest.warns(MatplotlibDeprecationWarning):
  1511. obj.hist2d(x, y, normed=True)
  1512. with pytest.warns(MatplotlibDeprecationWarning):
  1513. obj.hist2d(x, y, density=True, normed=True)
  1514. class TestScatter:
  1515. @image_comparison(['scatter'], style='mpl20', remove_text=True)
  1516. def test_scatter_plot(self):
  1517. data = {"x": np.array([3, 4, 2, 6]), "y": np.array([2, 5, 2, 3]),
  1518. "c": ['r', 'y', 'b', 'lime'], "s": [24, 15, 19, 29],
  1519. "c2": ['0.5', '0.6', '0.7', '0.8']}
  1520. fig, ax = plt.subplots()
  1521. ax.scatter(data["x"] - 1., data["y"] - 1., c=data["c"], s=data["s"])
  1522. ax.scatter(data["x"] + 1., data["y"] + 1., c=data["c2"], s=data["s"])
  1523. ax.scatter("x", "y", c="c", s="s", data=data)
  1524. @image_comparison(['scatter_marker.png'], remove_text=True)
  1525. def test_scatter_marker(self):
  1526. fig, (ax0, ax1, ax2) = plt.subplots(ncols=3)
  1527. ax0.scatter([3, 4, 2, 6], [2, 5, 2, 3],
  1528. c=[(1, 0, 0), 'y', 'b', 'lime'],
  1529. s=[60, 50, 40, 30],
  1530. edgecolors=['k', 'r', 'g', 'b'],
  1531. marker='s')
  1532. ax1.scatter([3, 4, 2, 6], [2, 5, 2, 3],
  1533. c=[(1, 0, 0), 'y', 'b', 'lime'],
  1534. s=[60, 50, 40, 30],
  1535. edgecolors=['k', 'r', 'g', 'b'],
  1536. marker=mmarkers.MarkerStyle('o', fillstyle='top'))
  1537. # unit area ellipse
  1538. rx, ry = 3, 1
  1539. area = rx * ry * np.pi
  1540. theta = np.linspace(0, 2 * np.pi, 21)
  1541. verts = np.column_stack([np.cos(theta) * rx / area,
  1542. np.sin(theta) * ry / area])
  1543. ax2.scatter([3, 4, 2, 6], [2, 5, 2, 3],
  1544. c=[(1, 0, 0), 'y', 'b', 'lime'],
  1545. s=[60, 50, 40, 30],
  1546. edgecolors=['k', 'r', 'g', 'b'],
  1547. marker=verts)
  1548. @image_comparison(['scatter_2D'], remove_text=True, extensions=['png'])
  1549. def test_scatter_2D(self):
  1550. x = np.arange(3)
  1551. y = np.arange(2)
  1552. x, y = np.meshgrid(x, y)
  1553. z = x + y
  1554. fig, ax = plt.subplots()
  1555. ax.scatter(x, y, c=z, s=200, edgecolors='face')
  1556. @check_figures_equal(extensions=["png"])
  1557. def test_scatter_decimal(self, fig_test, fig_ref):
  1558. x0 = np.array([1.5, 8.4, 5.3, 4.2])
  1559. y0 = np.array([1.1, 2.2, 3.3, 4.4])
  1560. x = np.array([Decimal(i) for i in x0])
  1561. y = np.array([Decimal(i) for i in y0])
  1562. c = ['r', 'y', 'b', 'lime']
  1563. s = [24, 15, 19, 29]
  1564. # Test image - scatter plot with Decimal() input
  1565. ax = fig_test.subplots()
  1566. ax.scatter(x, y, c=c, s=s)
  1567. # Reference image
  1568. ax = fig_ref.subplots()
  1569. ax.scatter(x0, y0, c=c, s=s)
  1570. def test_scatter_color(self):
  1571. # Try to catch cases where 'c' kwarg should have been used.
  1572. with pytest.raises(ValueError):
  1573. plt.scatter([1, 2], [1, 2], color=[0.1, 0.2])
  1574. with pytest.raises(ValueError):
  1575. plt.scatter([1, 2, 3], [1, 2, 3], color=[1, 2, 3])
  1576. def test_scatter_size_arg_size(self):
  1577. x = np.arange(4)
  1578. with pytest.raises(ValueError):
  1579. plt.scatter(x, x, x[1:])
  1580. with pytest.raises(ValueError):
  1581. plt.scatter(x[1:], x[1:], x)
  1582. @check_figures_equal(extensions=["png"])
  1583. def test_scatter_invalid_color(self, fig_test, fig_ref):
  1584. ax = fig_test.subplots()
  1585. cmap = plt.get_cmap("viridis", 16)
  1586. cmap.set_bad("k", 1)
  1587. # Set a nonuniform size to prevent the last call to `scatter` (plotting
  1588. # the invalid points separately in fig_ref) from using the marker
  1589. # stamping fast path, which would result in slightly offset markers.
  1590. ax.scatter(range(4), range(4),
  1591. c=[1, np.nan, 2, np.nan], s=[1, 2, 3, 4],
  1592. cmap=cmap, plotnonfinite=True)
  1593. ax = fig_ref.subplots()
  1594. cmap = plt.get_cmap("viridis", 16)
  1595. ax.scatter([0, 2], [0, 2], c=[1, 2], s=[1, 3], cmap=cmap)
  1596. ax.scatter([1, 3], [1, 3], s=[2, 4], color="k")
  1597. @check_figures_equal(extensions=["png"])
  1598. def test_scatter_no_invalid_color(self, fig_test, fig_ref):
  1599. # With plotninfinite=False we plot only 2 points.
  1600. ax = fig_test.subplots()
  1601. cmap = plt.get_cmap("viridis", 16)
  1602. cmap.set_bad("k", 1)
  1603. ax.scatter(range(4), range(4),
  1604. c=[1, np.nan, 2, np.nan], s=[1, 2, 3, 4],
  1605. cmap=cmap, plotnonfinite=False)
  1606. ax = fig_ref.subplots()
  1607. ax.scatter([0, 2], [0, 2], c=[1, 2], s=[1, 3], cmap=cmap)
  1608. @check_figures_equal(extensions=["png"])
  1609. def test_scatter_single_point(self, fig_test, fig_ref):
  1610. ax = fig_test.subplots()
  1611. ax.scatter(1, 1, c=1)
  1612. ax = fig_ref.subplots()
  1613. ax.scatter([1], [1], c=[1])
  1614. @check_figures_equal(extensions=["png"])
  1615. def test_scatter_different_shapes(self, fig_test, fig_ref):
  1616. x = np.arange(10)
  1617. ax = fig_test.subplots()
  1618. ax.scatter(x, x.reshape(2, 5), c=x.reshape(5, 2))
  1619. ax = fig_ref.subplots()
  1620. ax.scatter(x.reshape(5, 2), x, c=x.reshape(2, 5))
  1621. # Parameters for *test_scatter_c*. NB: assuming that the
  1622. # scatter plot will have 4 elements. The tuple scheme is:
  1623. # (*c* parameter case, exception regexp key or None if no exception)
  1624. params_test_scatter_c = [
  1625. # single string:
  1626. ('0.5', None),
  1627. # Single letter-sequences
  1628. (["rgby"], "conversion"),
  1629. # Special cases
  1630. ("red", None),
  1631. ("none", None),
  1632. (None, None),
  1633. (["r", "g", "b", "none"], None),
  1634. # Non-valid color spec (FWIW, 'jaune' means yellow in French)
  1635. ("jaune", "conversion"),
  1636. (["jaune"], "conversion"), # wrong type before wrong size
  1637. (["jaune"]*4, "conversion"),
  1638. # Value-mapping like
  1639. ([0.5]*3, None), # should emit a warning for user's eyes though
  1640. ([0.5]*4, None), # NB: no warning as matching size allows mapping
  1641. ([0.5]*5, "shape"),
  1642. # list of strings:
  1643. (['0.5', '0.4', '0.6', '0.7'], None),
  1644. (['0.5', 'red', '0.6', 'C5'], None),
  1645. (['0.5', 0.5, '0.6', 'C5'], "conversion"),
  1646. # RGB values
  1647. ([[1, 0, 0]], None),
  1648. ([[1, 0, 0]]*3, "shape"),
  1649. ([[1, 0, 0]]*4, None),
  1650. ([[1, 0, 0]]*5, "shape"),
  1651. # RGBA values
  1652. ([[1, 0, 0, 0.5]], None),
  1653. ([[1, 0, 0, 0.5]]*3, "shape"),
  1654. ([[1, 0, 0, 0.5]]*4, None),
  1655. ([[1, 0, 0, 0.5]]*5, "shape"),
  1656. # Mix of valid color specs
  1657. ([[1, 0, 0, 0.5]]*3 + [[1, 0, 0]], None),
  1658. ([[1, 0, 0, 0.5], "red", "0.0"], "shape"),
  1659. ([[1, 0, 0, 0.5], "red", "0.0", "C5"], None),
  1660. ([[1, 0, 0, 0.5], "red", "0.0", "C5", [0, 1, 0]], "shape"),
  1661. # Mix of valid and non valid color specs
  1662. ([[1, 0, 0, 0.5], "red", "jaune"], "conversion"),
  1663. ([[1, 0, 0, 0.5], "red", "0.0", "jaune"], "conversion"),
  1664. ([[1, 0, 0, 0.5], "red", "0.0", "C5", "jaune"], "conversion"),
  1665. ]
  1666. @pytest.mark.parametrize('c_case, re_key', params_test_scatter_c)
  1667. def test_scatter_c(self, c_case, re_key):
  1668. def get_next_color():
  1669. return 'blue' # currently unused
  1670. from matplotlib.axes import Axes
  1671. xsize = 4
  1672. # Additional checking of *c* (introduced in #11383).
  1673. REGEXP = {
  1674. "shape": "^'c' argument has [0-9]+ elements", # shape mismatch
  1675. "conversion": "^'c' argument must be a color", # bad vals
  1676. }
  1677. if re_key is None:
  1678. Axes._parse_scatter_color_args(
  1679. c=c_case, edgecolors="black", kwargs={}, xsize=xsize,
  1680. get_next_color_func=get_next_color)
  1681. else:
  1682. with pytest.raises(ValueError, match=REGEXP[re_key]):
  1683. Axes._parse_scatter_color_args(
  1684. c=c_case, edgecolors="black", kwargs={}, xsize=xsize,
  1685. get_next_color_func=get_next_color)
  1686. def _params(c=None, xsize=2, **kwargs):
  1687. edgecolors = kwargs.pop('edgecolors', None)
  1688. return (c, edgecolors, kwargs if kwargs is not None else {}, xsize)
  1689. _result = namedtuple('_result', 'c, colors')
  1690. @pytest.mark.parametrize('params, expected_result',
  1691. [(_params(),
  1692. _result(c='b', colors=np.array([[0, 0, 1, 1]]))),
  1693. (_params(c='r'),
  1694. _result(c='r', colors=np.array([[1, 0, 0, 1]]))),
  1695. (_params(c='r', colors='b'),
  1696. _result(c='r', colors=np.array([[1, 0, 0, 1]]))),
  1697. # color
  1698. (_params(color='b'),
  1699. _result(c='b', colors=np.array([[0, 0, 1, 1]]))),
  1700. (_params(color=['b', 'g']),
  1701. _result(c=['b', 'g'], colors=np.array([[0, 0, 1, 1], [0, .5, 0, 1]]))),
  1702. ])
  1703. def test_parse_scatter_color_args(params, expected_result):
  1704. def get_next_color():
  1705. return 'blue' # currently unused
  1706. from matplotlib.axes import Axes
  1707. c, colors, _edgecolors = Axes._parse_scatter_color_args(
  1708. *params, get_next_color_func=get_next_color)
  1709. assert c == expected_result.c
  1710. assert_allclose(colors, expected_result.colors)
  1711. del _params
  1712. del _result
  1713. @pytest.mark.parametrize('kwargs, expected_edgecolors',
  1714. [(dict(), None),
  1715. (dict(c='b'), None),
  1716. (dict(edgecolors='r'), 'r'),
  1717. (dict(edgecolors=['r', 'g']), ['r', 'g']),
  1718. (dict(edgecolor='r'), 'r'),
  1719. (dict(edgecolors='face'), 'face'),
  1720. (dict(edgecolors='none'), 'none'),
  1721. (dict(edgecolor='r', edgecolors='g'), 'r'),
  1722. (dict(c='b', edgecolor='r', edgecolors='g'), 'r'),
  1723. (dict(color='r'), 'r'),
  1724. (dict(color='r', edgecolor='g'), 'g'),
  1725. ])
  1726. def test_parse_scatter_color_args_edgecolors(kwargs, expected_edgecolors):
  1727. def get_next_color():
  1728. return 'blue' # currently unused
  1729. from matplotlib.axes import Axes
  1730. c = kwargs.pop('c', None)
  1731. edgecolors = kwargs.pop('edgecolors', None)
  1732. _, _, result_edgecolors = \
  1733. Axes._parse_scatter_color_args(c, edgecolors, kwargs, xsize=2,
  1734. get_next_color_func=get_next_color)
  1735. assert result_edgecolors == expected_edgecolors
  1736. def test_as_mpl_axes_api():
  1737. # tests the _as_mpl_axes api
  1738. from matplotlib.projections.polar import PolarAxes
  1739. import matplotlib.axes as maxes
  1740. class Polar:
  1741. def __init__(self):
  1742. self.theta_offset = 0
  1743. def _as_mpl_axes(self):
  1744. # implement the matplotlib axes interface
  1745. return PolarAxes, {'theta_offset': self.theta_offset}
  1746. prj = Polar()
  1747. prj2 = Polar()
  1748. prj2.theta_offset = np.pi
  1749. prj3 = Polar()
  1750. # testing axes creation with plt.axes
  1751. ax = plt.axes([0, 0, 1, 1], projection=prj)
  1752. assert type(ax) == PolarAxes
  1753. ax_via_gca = plt.gca(projection=prj)
  1754. assert ax_via_gca is ax
  1755. plt.close()
  1756. # testing axes creation with gca
  1757. ax = plt.gca(projection=prj)
  1758. assert type(ax) == maxes._subplots.subplot_class_factory(PolarAxes)
  1759. ax_via_gca = plt.gca(projection=prj)
  1760. assert ax_via_gca is ax
  1761. # try getting the axes given a different polar projection
  1762. with pytest.warns(UserWarning) as rec:
  1763. ax_via_gca = plt.gca(projection=prj2)
  1764. assert len(rec) == 1
  1765. assert 'Requested projection is different' in str(rec[0].message)
  1766. assert ax_via_gca is not ax
  1767. assert ax.get_theta_offset() == 0
  1768. assert ax_via_gca.get_theta_offset() == np.pi
  1769. # try getting the axes given an == (not is) polar projection
  1770. with pytest.warns(UserWarning):
  1771. ax_via_gca = plt.gca(projection=prj3)
  1772. assert len(rec) == 1
  1773. assert 'Requested projection is different' in str(rec[0].message)
  1774. assert ax_via_gca is ax
  1775. plt.close()
  1776. # testing axes creation with subplot
  1777. ax = plt.subplot(121, projection=prj)
  1778. assert type(ax) == maxes._subplots.subplot_class_factory(PolarAxes)
  1779. plt.close()
  1780. def test_pyplot_axes():
  1781. # test focusing of Axes in other Figure
  1782. fig1, ax1 = plt.subplots()
  1783. fig2, ax2 = plt.subplots()
  1784. plt.sca(ax1)
  1785. assert ax1 is plt.gca()
  1786. assert fig1 is plt.gcf()
  1787. plt.close(fig1)
  1788. plt.close(fig2)
  1789. @image_comparison(['log_scales'])
  1790. def test_log_scales():
  1791. fig = plt.figure()
  1792. ax = fig.add_subplot(1, 1, 1)
  1793. ax.plot(np.log(np.linspace(0.1, 100)))
  1794. ax.set_yscale('log', basey=5.5)
  1795. ax.invert_yaxis()
  1796. ax.set_xscale('log', basex=9.0)
  1797. def test_log_scales_no_data():
  1798. _, ax = plt.subplots()
  1799. ax.set(xscale="log", yscale="log")
  1800. ax.xaxis.set_major_locator(mticker.MultipleLocator(1))
  1801. assert ax.get_xlim() == ax.get_ylim() == (1, 10)
  1802. def test_log_scales_invalid():
  1803. fig = plt.figure()
  1804. ax = fig.add_subplot(1, 1, 1)
  1805. ax.set_xscale('log')
  1806. with pytest.warns(UserWarning, match='Attempted to set non-positive'):
  1807. ax.set_xlim(-1, 10)
  1808. ax.set_yscale('log')
  1809. with pytest.warns(UserWarning, match='Attempted to set non-positive'):
  1810. ax.set_ylim(-1, 10)
  1811. def test_polar_no_data():
  1812. plt.subplot(projection="polar")
  1813. ax = plt.gca()
  1814. assert ax.get_rmin() == 0 and ax.get_rmax() == 1
  1815. plt.close("all")
  1816. # Used to behave differently (by triggering an autoscale with no data).
  1817. plt.polar()
  1818. ax = plt.gca()
  1819. assert ax.get_rmin() == 0 and ax.get_rmax() == 1
  1820. @image_comparison(['stackplot_test_image', 'stackplot_test_image'])
  1821. def test_stackplot():
  1822. fig = plt.figure()
  1823. x = np.linspace(0, 10, 10)
  1824. y1 = 1.0 * x
  1825. y2 = 2.0 * x + 1
  1826. y3 = 3.0 * x + 2
  1827. ax = fig.add_subplot(1, 1, 1)
  1828. ax.stackplot(x, y1, y2, y3)
  1829. ax.set_xlim((0, 10))
  1830. ax.set_ylim((0, 70))
  1831. # Reuse testcase from above for a labeled data test
  1832. data = {"x": x, "y1": y1, "y2": y2, "y3": y3}
  1833. fig = plt.figure()
  1834. ax = fig.add_subplot(1, 1, 1)
  1835. ax.stackplot("x", "y1", "y2", "y3", data=data)
  1836. ax.set_xlim((0, 10))
  1837. ax.set_ylim((0, 70))
  1838. @image_comparison(['stackplot_test_baseline'], remove_text=True)
  1839. def test_stackplot_baseline():
  1840. np.random.seed(0)
  1841. def layers(n, m):
  1842. a = np.zeros((m, n))
  1843. for i in range(n):
  1844. for j in range(5):
  1845. x = 1 / (.1 + np.random.random())
  1846. y = 2 * np.random.random() - .5
  1847. z = 10 / (.1 + np.random.random())
  1848. a[:, i] += x * np.exp(-((np.arange(m) / m - y) * z) ** 2)
  1849. return a
  1850. d = layers(3, 100)
  1851. d[50, :] = 0 # test for fixed weighted wiggle (issue #6313)
  1852. fig, axs = plt.subplots(2, 2)
  1853. axs[0, 0].stackplot(range(100), d.T, baseline='zero')
  1854. axs[0, 1].stackplot(range(100), d.T, baseline='sym')
  1855. axs[1, 0].stackplot(range(100), d.T, baseline='wiggle')
  1856. axs[1, 1].stackplot(range(100), d.T, baseline='weighted_wiggle')
  1857. def _bxp_test_helper(
  1858. stats_kwargs={}, transform_stats=lambda s: s, bxp_kwargs={}):
  1859. np.random.seed(937)
  1860. logstats = mpl.cbook.boxplot_stats(
  1861. np.random.lognormal(mean=1.25, sigma=1., size=(37, 4)), **stats_kwargs)
  1862. fig, ax = plt.subplots()
  1863. if bxp_kwargs.get('vert', True):
  1864. ax.set_yscale('log')
  1865. else:
  1866. ax.set_xscale('log')
  1867. # Work around baseline images generate back when bxp did not respect the
  1868. # boxplot.boxprops.linewidth rcParam when patch_artist is False.
  1869. if not bxp_kwargs.get('patch_artist', False):
  1870. mpl.rcParams['boxplot.boxprops.linewidth'] = \
  1871. mpl.rcParams['lines.linewidth']
  1872. ax.bxp(transform_stats(logstats), **bxp_kwargs)
  1873. @image_comparison(['bxp_baseline.png'],
  1874. savefig_kwarg={'dpi': 40},
  1875. style='default')
  1876. def test_bxp_baseline():
  1877. _bxp_test_helper()
  1878. @image_comparison(['bxp_rangewhis.png'],
  1879. savefig_kwarg={'dpi': 40},
  1880. style='default')
  1881. def test_bxp_rangewhis():
  1882. _bxp_test_helper(stats_kwargs=dict(whis=[0, 100]))
  1883. @image_comparison(['bxp_precentilewhis.png'],
  1884. savefig_kwarg={'dpi': 40},
  1885. style='default')
  1886. def test_bxp_precentilewhis():
  1887. _bxp_test_helper(stats_kwargs=dict(whis=[5, 95]))
  1888. @image_comparison(['bxp_with_xlabels.png'],
  1889. savefig_kwarg={'dpi': 40},
  1890. style='default')
  1891. def test_bxp_with_xlabels():
  1892. def transform(stats):
  1893. for s, label in zip(stats, list('ABCD')):
  1894. s['label'] = label
  1895. return stats
  1896. _bxp_test_helper(transform_stats=transform)
  1897. @image_comparison(['bxp_horizontal.png'],
  1898. remove_text=True,
  1899. savefig_kwarg={'dpi': 40},
  1900. style='default',
  1901. tol=0.1)
  1902. def test_bxp_horizontal():
  1903. _bxp_test_helper(bxp_kwargs=dict(vert=False))
  1904. @image_comparison(['bxp_with_ylabels.png'],
  1905. savefig_kwarg={'dpi': 40},
  1906. style='default',
  1907. tol=0.1)
  1908. def test_bxp_with_ylabels():
  1909. def transform(stats):
  1910. for s, label in zip(stats, list('ABCD')):
  1911. s['label'] = label
  1912. return stats
  1913. _bxp_test_helper(transform_stats=transform, bxp_kwargs=dict(vert=False))
  1914. @image_comparison(['bxp_patchartist.png'],
  1915. remove_text=True,
  1916. savefig_kwarg={'dpi': 40},
  1917. style='default')
  1918. def test_bxp_patchartist():
  1919. _bxp_test_helper(bxp_kwargs=dict(patch_artist=True))
  1920. @image_comparison(['bxp_custompatchartist.png'],
  1921. remove_text=True,
  1922. savefig_kwarg={'dpi': 100},
  1923. style='default')
  1924. def test_bxp_custompatchartist():
  1925. _bxp_test_helper(bxp_kwargs=dict(
  1926. patch_artist=True,
  1927. boxprops=dict(facecolor='yellow', edgecolor='green', ls=':')))
  1928. @image_comparison(['bxp_customoutlier.png'],
  1929. remove_text=True,
  1930. savefig_kwarg={'dpi': 40},
  1931. style='default')
  1932. def test_bxp_customoutlier():
  1933. _bxp_test_helper(bxp_kwargs=dict(
  1934. flierprops=dict(linestyle='none', marker='d', mfc='g')))
  1935. @image_comparison(['bxp_withmean_custompoint.png'],
  1936. remove_text=True,
  1937. savefig_kwarg={'dpi': 40},
  1938. style='default')
  1939. def test_bxp_showcustommean():
  1940. _bxp_test_helper(bxp_kwargs=dict(
  1941. showmeans=True,
  1942. meanprops=dict(linestyle='none', marker='d', mfc='green'),
  1943. ))
  1944. @image_comparison(['bxp_custombox.png'],
  1945. remove_text=True,
  1946. savefig_kwarg={'dpi': 40},
  1947. style='default')
  1948. def test_bxp_custombox():
  1949. _bxp_test_helper(bxp_kwargs=dict(
  1950. boxprops=dict(linestyle='--', color='b', lw=3)))
  1951. @image_comparison(['bxp_custommedian.png'],
  1952. remove_text=True,
  1953. savefig_kwarg={'dpi': 40},
  1954. style='default')
  1955. def test_bxp_custommedian():
  1956. _bxp_test_helper(bxp_kwargs=dict(
  1957. medianprops=dict(linestyle='--', color='b', lw=3)))
  1958. @image_comparison(['bxp_customcap.png'],
  1959. remove_text=True,
  1960. savefig_kwarg={'dpi': 40},
  1961. style='default')
  1962. def test_bxp_customcap():
  1963. _bxp_test_helper(bxp_kwargs=dict(
  1964. capprops=dict(linestyle='--', color='g', lw=3)))
  1965. @image_comparison(['bxp_customwhisker.png'],
  1966. remove_text=True,
  1967. savefig_kwarg={'dpi': 40},
  1968. style='default')
  1969. def test_bxp_customwhisker():
  1970. _bxp_test_helper(bxp_kwargs=dict(
  1971. whiskerprops=dict(linestyle='-', color='m', lw=3)))
  1972. @image_comparison(['bxp_withnotch.png'],
  1973. remove_text=True,
  1974. savefig_kwarg={'dpi': 40},
  1975. style='default')
  1976. def test_bxp_shownotches():
  1977. _bxp_test_helper(bxp_kwargs=dict(shownotches=True))
  1978. @image_comparison(['bxp_nocaps.png'],
  1979. remove_text=True,
  1980. savefig_kwarg={'dpi': 40},
  1981. style='default')
  1982. def test_bxp_nocaps():
  1983. _bxp_test_helper(bxp_kwargs=dict(showcaps=False))
  1984. @image_comparison(['bxp_nobox.png'],
  1985. remove_text=True,
  1986. savefig_kwarg={'dpi': 40},
  1987. style='default')
  1988. def test_bxp_nobox():
  1989. _bxp_test_helper(bxp_kwargs=dict(showbox=False))
  1990. @image_comparison(['bxp_no_flier_stats.png'],
  1991. remove_text=True,
  1992. savefig_kwarg={'dpi': 40},
  1993. style='default')
  1994. def test_bxp_no_flier_stats():
  1995. def transform(stats):
  1996. for s in stats:
  1997. s.pop('fliers', None)
  1998. return stats
  1999. _bxp_test_helper(transform_stats=transform,
  2000. bxp_kwargs=dict(showfliers=False))
  2001. @image_comparison(['bxp_withmean_point.png'],
  2002. remove_text=True,
  2003. savefig_kwarg={'dpi': 40},
  2004. style='default')
  2005. def test_bxp_showmean():
  2006. _bxp_test_helper(bxp_kwargs=dict(showmeans=True, meanline=False))
  2007. @image_comparison(['bxp_withmean_line.png'],
  2008. remove_text=True,
  2009. savefig_kwarg={'dpi': 40},
  2010. style='default')
  2011. def test_bxp_showmeanasline():
  2012. _bxp_test_helper(bxp_kwargs=dict(showmeans=True, meanline=True))
  2013. @image_comparison(['bxp_scalarwidth.png'],
  2014. remove_text=True,
  2015. savefig_kwarg={'dpi': 40},
  2016. style='default')
  2017. def test_bxp_scalarwidth():
  2018. _bxp_test_helper(bxp_kwargs=dict(widths=.25))
  2019. @image_comparison(['bxp_customwidths.png'],
  2020. remove_text=True,
  2021. savefig_kwarg={'dpi': 40},
  2022. style='default')
  2023. def test_bxp_customwidths():
  2024. _bxp_test_helper(bxp_kwargs=dict(widths=[0.10, 0.25, 0.65, 0.85]))
  2025. @image_comparison(['bxp_custompositions.png'],
  2026. remove_text=True,
  2027. savefig_kwarg={'dpi': 40},
  2028. style='default')
  2029. def test_bxp_custompositions():
  2030. _bxp_test_helper(bxp_kwargs=dict(positions=[1, 5, 6, 7]))
  2031. def test_bxp_bad_widths():
  2032. with pytest.raises(ValueError):
  2033. _bxp_test_helper(bxp_kwargs=dict(widths=[1]))
  2034. def test_bxp_bad_positions():
  2035. with pytest.raises(ValueError):
  2036. _bxp_test_helper(bxp_kwargs=dict(positions=[2, 3]))
  2037. @image_comparison(['boxplot', 'boxplot'], tol=1.28, style='default')
  2038. def test_boxplot():
  2039. # Randomness used for bootstrapping.
  2040. np.random.seed(937)
  2041. x = np.linspace(-7, 7, 140)
  2042. x = np.hstack([-25, x, 25])
  2043. fig, ax = plt.subplots()
  2044. ax.boxplot([x, x], bootstrap=10000, notch=1)
  2045. ax.set_ylim((-30, 30))
  2046. # Reuse testcase from above for a labeled data test
  2047. data = {"x": [x, x]}
  2048. fig, ax = plt.subplots()
  2049. ax.boxplot("x", bootstrap=10000, notch=1, data=data)
  2050. ax.set_ylim((-30, 30))
  2051. @image_comparison(['boxplot_sym2.png'], remove_text=True, style='default')
  2052. def test_boxplot_sym2():
  2053. # Randomness used for bootstrapping.
  2054. np.random.seed(937)
  2055. x = np.linspace(-7, 7, 140)
  2056. x = np.hstack([-25, x, 25])
  2057. fig, [ax1, ax2] = plt.subplots(1, 2)
  2058. ax1.boxplot([x, x], bootstrap=10000, sym='^')
  2059. ax1.set_ylim((-30, 30))
  2060. ax2.boxplot([x, x], bootstrap=10000, sym='g')
  2061. ax2.set_ylim((-30, 30))
  2062. @image_comparison(['boxplot_sym.png'],
  2063. remove_text=True,
  2064. savefig_kwarg={'dpi': 40},
  2065. style='default')
  2066. def test_boxplot_sym():
  2067. x = np.linspace(-7, 7, 140)
  2068. x = np.hstack([-25, x, 25])
  2069. fig, ax = plt.subplots()
  2070. ax.boxplot([x, x], sym='gs')
  2071. ax.set_ylim((-30, 30))
  2072. @image_comparison(['boxplot_autorange_false_whiskers.png',
  2073. 'boxplot_autorange_true_whiskers.png'],
  2074. style='default')
  2075. def test_boxplot_autorange_whiskers():
  2076. # Randomness used for bootstrapping.
  2077. np.random.seed(937)
  2078. x = np.ones(140)
  2079. x = np.hstack([0, x, 2])
  2080. fig1, ax1 = plt.subplots()
  2081. ax1.boxplot([x, x], bootstrap=10000, notch=1)
  2082. ax1.set_ylim((-5, 5))
  2083. fig2, ax2 = plt.subplots()
  2084. ax2.boxplot([x, x], bootstrap=10000, notch=1, autorange=True)
  2085. ax2.set_ylim((-5, 5))
  2086. def _rc_test_bxp_helper(ax, rc_dict):
  2087. x = np.linspace(-7, 7, 140)
  2088. x = np.hstack([-25, x, 25])
  2089. with matplotlib.rc_context(rc_dict):
  2090. ax.boxplot([x, x])
  2091. return ax
  2092. @image_comparison(['boxplot_rc_parameters'],
  2093. savefig_kwarg={'dpi': 100}, remove_text=True,
  2094. tol=1, style='default')
  2095. def test_boxplot_rc_parameters():
  2096. # Randomness used for bootstrapping.
  2097. np.random.seed(937)
  2098. fig, ax = plt.subplots(3)
  2099. rc_axis0 = {
  2100. 'boxplot.notch': True,
  2101. 'boxplot.whiskers': [5, 95],
  2102. 'boxplot.bootstrap': 10000,
  2103. 'boxplot.flierprops.color': 'b',
  2104. 'boxplot.flierprops.marker': 'o',
  2105. 'boxplot.flierprops.markerfacecolor': 'g',
  2106. 'boxplot.flierprops.markeredgecolor': 'b',
  2107. 'boxplot.flierprops.markersize': 5,
  2108. 'boxplot.flierprops.linestyle': '--',
  2109. 'boxplot.flierprops.linewidth': 2.0,
  2110. 'boxplot.boxprops.color': 'r',
  2111. 'boxplot.boxprops.linewidth': 2.0,
  2112. 'boxplot.boxprops.linestyle': '--',
  2113. 'boxplot.capprops.color': 'c',
  2114. 'boxplot.capprops.linewidth': 2.0,
  2115. 'boxplot.capprops.linestyle': '--',
  2116. 'boxplot.medianprops.color': 'k',
  2117. 'boxplot.medianprops.linewidth': 2.0,
  2118. 'boxplot.medianprops.linestyle': '--',
  2119. }
  2120. rc_axis1 = {
  2121. 'boxplot.vertical': False,
  2122. 'boxplot.whiskers': [0, 100],
  2123. 'boxplot.patchartist': True,
  2124. }
  2125. rc_axis2 = {
  2126. 'boxplot.whiskers': 2.0,
  2127. 'boxplot.showcaps': False,
  2128. 'boxplot.showbox': False,
  2129. 'boxplot.showfliers': False,
  2130. 'boxplot.showmeans': True,
  2131. 'boxplot.meanline': True,
  2132. 'boxplot.meanprops.color': 'c',
  2133. 'boxplot.meanprops.linewidth': 2.0,
  2134. 'boxplot.meanprops.linestyle': '--',
  2135. 'boxplot.whiskerprops.color': 'r',
  2136. 'boxplot.whiskerprops.linewidth': 2.0,
  2137. 'boxplot.whiskerprops.linestyle': '-.',
  2138. }
  2139. dict_list = [rc_axis0, rc_axis1, rc_axis2]
  2140. for axis, rc_axis in zip(ax, dict_list):
  2141. _rc_test_bxp_helper(axis, rc_axis)
  2142. assert (matplotlib.patches.PathPatch in
  2143. [type(t) for t in ax[1].get_children()])
  2144. @image_comparison(['boxplot_with_CIarray.png'],
  2145. remove_text=True, savefig_kwarg={'dpi': 40}, style='default')
  2146. def test_boxplot_with_CIarray():
  2147. # Randomness used for bootstrapping.
  2148. np.random.seed(937)
  2149. x = np.linspace(-7, 7, 140)
  2150. x = np.hstack([-25, x, 25])
  2151. fig = plt.figure()
  2152. ax = fig.add_subplot(111)
  2153. CIs = np.array([[-1.5, 3.], [-1., 3.5]])
  2154. # show a boxplot with Matplotlib medians and confidence intervals, and
  2155. # another with manual values
  2156. ax.boxplot([x, x], bootstrap=10000, usermedians=[None, 1.0],
  2157. conf_intervals=CIs, notch=1)
  2158. ax.set_ylim((-30, 30))
  2159. @image_comparison(['boxplot_no_inverted_whisker.png'],
  2160. remove_text=True, savefig_kwarg={'dpi': 40}, style='default')
  2161. def test_boxplot_no_weird_whisker():
  2162. x = np.array([3, 9000, 150, 88, 350, 200000, 1400, 960],
  2163. dtype=np.float64)
  2164. ax1 = plt.axes()
  2165. ax1.boxplot(x)
  2166. ax1.set_yscale('log')
  2167. ax1.yaxis.grid(False, which='minor')
  2168. ax1.xaxis.grid(False)
  2169. def test_boxplot_bad_medians_1():
  2170. x = np.linspace(-7, 7, 140)
  2171. x = np.hstack([-25, x, 25])
  2172. fig, ax = plt.subplots()
  2173. with pytest.raises(ValueError):
  2174. ax.boxplot(x, usermedians=[1, 2])
  2175. def test_boxplot_bad_medians_2():
  2176. x = np.linspace(-7, 7, 140)
  2177. x = np.hstack([-25, x, 25])
  2178. fig, ax = plt.subplots()
  2179. with pytest.raises(ValueError):
  2180. ax.boxplot([x, x], usermedians=[[1, 2], [1, 2]])
  2181. def test_boxplot_bad_ci_1():
  2182. x = np.linspace(-7, 7, 140)
  2183. x = np.hstack([-25, x, 25])
  2184. fig, ax = plt.subplots()
  2185. with pytest.raises(ValueError):
  2186. ax.boxplot([x, x], conf_intervals=[[1, 2]])
  2187. def test_boxplot_zorder():
  2188. x = np.arange(10)
  2189. fix, ax = plt.subplots()
  2190. assert ax.boxplot(x)['boxes'][0].get_zorder() == 2
  2191. assert ax.boxplot(x, zorder=10)['boxes'][0].get_zorder() == 10
  2192. def test_boxplot_bad_ci_2():
  2193. x = np.linspace(-7, 7, 140)
  2194. x = np.hstack([-25, x, 25])
  2195. fig, ax = plt.subplots()
  2196. with pytest.raises(ValueError):
  2197. ax.boxplot([x, x], conf_intervals=[[1, 2], [1]])
  2198. @image_comparison(['boxplot_mod_artists_after_plotting.png'],
  2199. remove_text=True, savefig_kwarg={'dpi': 40}, style='default')
  2200. def test_boxplot_mod_artist_after_plotting():
  2201. x = [0.15, 0.11, 0.06, 0.06, 0.12, 0.56, -0.56]
  2202. fig, ax = plt.subplots()
  2203. bp = ax.boxplot(x, sym="o")
  2204. for key in bp:
  2205. for obj in bp[key]:
  2206. obj.set_color('green')
  2207. @image_comparison(['violinplot_vert_baseline.png',
  2208. 'violinplot_vert_baseline.png'])
  2209. def test_vert_violinplot_baseline():
  2210. # First 9 digits of frac(sqrt(2))
  2211. np.random.seed(414213562)
  2212. data = [np.random.normal(size=100) for i in range(4)]
  2213. ax = plt.axes()
  2214. ax.violinplot(data, positions=range(4), showmeans=0, showextrema=0,
  2215. showmedians=0)
  2216. # Reuse testcase from above for a labeled data test
  2217. data = {"d": data}
  2218. fig, ax = plt.subplots()
  2219. ax = plt.axes()
  2220. ax.violinplot("d", positions=range(4), showmeans=0, showextrema=0,
  2221. showmedians=0, data=data)
  2222. @image_comparison(['violinplot_vert_showmeans.png'])
  2223. def test_vert_violinplot_showmeans():
  2224. ax = plt.axes()
  2225. # First 9 digits of frac(sqrt(3))
  2226. np.random.seed(732050807)
  2227. data = [np.random.normal(size=100) for i in range(4)]
  2228. ax.violinplot(data, positions=range(4), showmeans=1, showextrema=0,
  2229. showmedians=0)
  2230. @image_comparison(['violinplot_vert_showextrema.png'])
  2231. def test_vert_violinplot_showextrema():
  2232. ax = plt.axes()
  2233. # First 9 digits of frac(sqrt(5))
  2234. np.random.seed(236067977)
  2235. data = [np.random.normal(size=100) for i in range(4)]
  2236. ax.violinplot(data, positions=range(4), showmeans=0, showextrema=1,
  2237. showmedians=0)
  2238. @image_comparison(['violinplot_vert_showmedians.png'])
  2239. def test_vert_violinplot_showmedians():
  2240. ax = plt.axes()
  2241. # First 9 digits of frac(sqrt(7))
  2242. np.random.seed(645751311)
  2243. data = [np.random.normal(size=100) for i in range(4)]
  2244. ax.violinplot(data, positions=range(4), showmeans=0, showextrema=0,
  2245. showmedians=1)
  2246. @image_comparison(['violinplot_vert_showall.png'])
  2247. def test_vert_violinplot_showall():
  2248. ax = plt.axes()
  2249. # First 9 digits of frac(sqrt(11))
  2250. np.random.seed(316624790)
  2251. data = [np.random.normal(size=100) for i in range(4)]
  2252. ax.violinplot(data, positions=range(4), showmeans=1, showextrema=1,
  2253. showmedians=1,
  2254. quantiles=[[0.1, 0.9], [0.2, 0.8], [0.3, 0.7], [0.4, 0.6]])
  2255. @image_comparison(['violinplot_vert_custompoints_10.png'])
  2256. def test_vert_violinplot_custompoints_10():
  2257. ax = plt.axes()
  2258. # First 9 digits of frac(sqrt(13))
  2259. np.random.seed(605551275)
  2260. data = [np.random.normal(size=100) for i in range(4)]
  2261. ax.violinplot(data, positions=range(4), showmeans=0, showextrema=0,
  2262. showmedians=0, points=10)
  2263. @image_comparison(['violinplot_vert_custompoints_200.png'])
  2264. def test_vert_violinplot_custompoints_200():
  2265. ax = plt.axes()
  2266. # First 9 digits of frac(sqrt(17))
  2267. np.random.seed(123105625)
  2268. data = [np.random.normal(size=100) for i in range(4)]
  2269. ax.violinplot(data, positions=range(4), showmeans=0, showextrema=0,
  2270. showmedians=0, points=200)
  2271. @image_comparison(['violinplot_horiz_baseline.png'])
  2272. def test_horiz_violinplot_baseline():
  2273. ax = plt.axes()
  2274. # First 9 digits of frac(sqrt(19))
  2275. np.random.seed(358898943)
  2276. data = [np.random.normal(size=100) for i in range(4)]
  2277. ax.violinplot(data, positions=range(4), vert=False, showmeans=0,
  2278. showextrema=0, showmedians=0)
  2279. @image_comparison(['violinplot_horiz_showmedians.png'])
  2280. def test_horiz_violinplot_showmedians():
  2281. ax = plt.axes()
  2282. # First 9 digits of frac(sqrt(23))
  2283. np.random.seed(795831523)
  2284. data = [np.random.normal(size=100) for i in range(4)]
  2285. ax.violinplot(data, positions=range(4), vert=False, showmeans=0,
  2286. showextrema=0, showmedians=1)
  2287. @image_comparison(['violinplot_horiz_showmeans.png'])
  2288. def test_horiz_violinplot_showmeans():
  2289. ax = plt.axes()
  2290. # First 9 digits of frac(sqrt(29))
  2291. np.random.seed(385164807)
  2292. data = [np.random.normal(size=100) for i in range(4)]
  2293. ax.violinplot(data, positions=range(4), vert=False, showmeans=1,
  2294. showextrema=0, showmedians=0)
  2295. @image_comparison(['violinplot_horiz_showextrema.png'])
  2296. def test_horiz_violinplot_showextrema():
  2297. ax = plt.axes()
  2298. # First 9 digits of frac(sqrt(31))
  2299. np.random.seed(567764362)
  2300. data = [np.random.normal(size=100) for i in range(4)]
  2301. ax.violinplot(data, positions=range(4), vert=False, showmeans=0,
  2302. showextrema=1, showmedians=0)
  2303. @image_comparison(['violinplot_horiz_showall.png'])
  2304. def test_horiz_violinplot_showall():
  2305. ax = plt.axes()
  2306. # First 9 digits of frac(sqrt(37))
  2307. np.random.seed(82762530)
  2308. data = [np.random.normal(size=100) for i in range(4)]
  2309. ax.violinplot(data, positions=range(4), vert=False, showmeans=1,
  2310. showextrema=1, showmedians=1,
  2311. quantiles=[[0.1, 0.9], [0.2, 0.8], [0.3, 0.7], [0.4, 0.6]])
  2312. @image_comparison(['violinplot_horiz_custompoints_10.png'])
  2313. def test_horiz_violinplot_custompoints_10():
  2314. ax = plt.axes()
  2315. # First 9 digits of frac(sqrt(41))
  2316. np.random.seed(403124237)
  2317. data = [np.random.normal(size=100) for i in range(4)]
  2318. ax.violinplot(data, positions=range(4), vert=False, showmeans=0,
  2319. showextrema=0, showmedians=0, points=10)
  2320. @image_comparison(['violinplot_horiz_custompoints_200.png'])
  2321. def test_horiz_violinplot_custompoints_200():
  2322. ax = plt.axes()
  2323. # First 9 digits of frac(sqrt(43))
  2324. np.random.seed(557438524)
  2325. data = [np.random.normal(size=100) for i in range(4)]
  2326. ax.violinplot(data, positions=range(4), vert=False, showmeans=0,
  2327. showextrema=0, showmedians=0, points=200)
  2328. def test_violinplot_bad_positions():
  2329. ax = plt.axes()
  2330. # First 9 digits of frac(sqrt(47))
  2331. np.random.seed(855654600)
  2332. data = [np.random.normal(size=100) for i in range(4)]
  2333. with pytest.raises(ValueError):
  2334. ax.violinplot(data, positions=range(5))
  2335. def test_violinplot_bad_widths():
  2336. ax = plt.axes()
  2337. # First 9 digits of frac(sqrt(53))
  2338. np.random.seed(280109889)
  2339. data = [np.random.normal(size=100) for i in range(4)]
  2340. with pytest.raises(ValueError):
  2341. ax.violinplot(data, positions=range(4), widths=[1, 2, 3])
  2342. def test_violinplot_bad_quantiles():
  2343. ax = plt.axes()
  2344. # First 9 digits of frac(sqrt(73))
  2345. np.random.seed(544003745)
  2346. data = [np.random.normal(size=100)]
  2347. # Different size quantile list and plots
  2348. with pytest.raises(ValueError):
  2349. ax.violinplot(data, quantiles=[[0.1, 0.2], [0.5, 0.7]])
  2350. def test_violinplot_outofrange_quantiles():
  2351. ax = plt.axes()
  2352. # First 9 digits of frac(sqrt(79))
  2353. np.random.seed(888194417)
  2354. data = [np.random.normal(size=100)]
  2355. # Quantile value above 100
  2356. with pytest.raises(ValueError):
  2357. ax.violinplot(data, quantiles=[[0.1, 0.2, 0.3, 1.05]])
  2358. # Quantile value below 0
  2359. with pytest.raises(ValueError):
  2360. ax.violinplot(data, quantiles=[[-0.05, 0.2, 0.3, 0.75]])
  2361. @check_figures_equal(extensions=["png"])
  2362. def test_violinplot_single_list_quantiles(fig_test, fig_ref):
  2363. # Ensures quantile list for 1D can be passed in as single list
  2364. # First 9 digits of frac(sqrt(83))
  2365. np.random.seed(110433579)
  2366. data = [np.random.normal(size=100)]
  2367. # Test image
  2368. ax = fig_test.subplots()
  2369. ax.violinplot(data, quantiles=[0.1, 0.3, 0.9])
  2370. # Reference image
  2371. ax = fig_ref.subplots()
  2372. ax.violinplot(data, quantiles=[[0.1, 0.3, 0.9]])
  2373. def test_manage_xticks():
  2374. _, ax = plt.subplots()
  2375. ax.set_xlim(0, 4)
  2376. old_xlim = ax.get_xlim()
  2377. np.random.seed(0)
  2378. y1 = np.random.normal(10, 3, 20)
  2379. y2 = np.random.normal(3, 1, 20)
  2380. ax.boxplot([y1, y2], positions=[1, 2], manage_ticks=False)
  2381. new_xlim = ax.get_xlim()
  2382. assert_array_equal(old_xlim, new_xlim)
  2383. def test_boxplot_not_single():
  2384. fig, ax = plt.subplots()
  2385. ax.boxplot(np.random.rand(100), positions=[3])
  2386. ax.boxplot(np.random.rand(100), positions=[5])
  2387. fig.canvas.draw()
  2388. assert ax.get_xlim() == (2.5, 5.5)
  2389. assert list(ax.get_xticks()) == [3, 5]
  2390. assert [t.get_text() for t in ax.get_xticklabels()] == ["3", "5"]
  2391. def test_tick_space_size_0():
  2392. # allow font size to be zero, which affects ticks when there is
  2393. # no other text in the figure.
  2394. plt.plot([0, 1], [0, 1])
  2395. matplotlib.rcParams.update({'font.size': 0})
  2396. b = io.BytesIO()
  2397. plt.savefig(b, dpi=80, format='raw')
  2398. @image_comparison(['errorbar_basic', 'errorbar_mixed', 'errorbar_basic'])
  2399. def test_errorbar():
  2400. x = np.arange(0.1, 4, 0.5)
  2401. y = np.exp(-x)
  2402. yerr = 0.1 + 0.2*np.sqrt(x)
  2403. xerr = 0.1 + yerr
  2404. # First illustrate basic pyplot interface, using defaults where possible.
  2405. fig = plt.figure()
  2406. ax = fig.gca()
  2407. ax.errorbar(x, y, xerr=0.2, yerr=0.4)
  2408. ax.set_title("Simplest errorbars, 0.2 in x, 0.4 in y")
  2409. # Now switch to a more OO interface to exercise more features.
  2410. fig, axs = plt.subplots(nrows=2, ncols=2, sharex=True)
  2411. ax = axs[0, 0]
  2412. # Try a Nx1 shaped error just to check
  2413. with pytest.warns(MatplotlibDeprecationWarning):
  2414. ax.errorbar(x, y, yerr=np.reshape(yerr, (len(y), 1)), fmt='o')
  2415. ax.set_title('Vert. symmetric')
  2416. # With 4 subplots, reduce the number of axis ticks to avoid crowding.
  2417. ax.locator_params(nbins=4)
  2418. ax = axs[0, 1]
  2419. ax.errorbar(x, y, xerr=xerr, fmt='o', alpha=0.4)
  2420. ax.set_title('Hor. symmetric w/ alpha')
  2421. ax = axs[1, 0]
  2422. ax.errorbar(x, y, yerr=[yerr, 2*yerr], xerr=[xerr, 2*xerr], fmt='--o')
  2423. ax.set_title('H, V asymmetric')
  2424. ax = axs[1, 1]
  2425. ax.set_yscale('log')
  2426. # Here we have to be careful to keep all y values positive:
  2427. ylower = np.maximum(1e-2, y - yerr)
  2428. yerr_lower = y - ylower
  2429. ax.errorbar(x, y, yerr=[yerr_lower, 2*yerr], xerr=xerr,
  2430. fmt='o', ecolor='g', capthick=2)
  2431. ax.set_title('Mixed sym., log y')
  2432. fig.suptitle('Variable errorbars')
  2433. # Reuse the first testcase from above for a labeled data test
  2434. data = {"x": x, "y": y}
  2435. fig = plt.figure()
  2436. ax = fig.gca()
  2437. ax.errorbar("x", "y", xerr=0.2, yerr=0.4, data=data)
  2438. ax.set_title("Simplest errorbars, 0.2 in x, 0.4 in y")
  2439. def test_errorbar_colorcycle():
  2440. f, ax = plt.subplots()
  2441. x = np.arange(10)
  2442. y = 2*x
  2443. e1, _, _ = ax.errorbar(x, y, c=None)
  2444. e2, _, _ = ax.errorbar(x, 2*y, c=None)
  2445. ln1, = ax.plot(x, 4*y)
  2446. assert mcolors.to_rgba(e1.get_color()) == mcolors.to_rgba('C0')
  2447. assert mcolors.to_rgba(e2.get_color()) == mcolors.to_rgba('C1')
  2448. assert mcolors.to_rgba(ln1.get_color()) == mcolors.to_rgba('C2')
  2449. def test_errorbar_shape():
  2450. fig = plt.figure()
  2451. ax = fig.gca()
  2452. x = np.arange(0.1, 4, 0.5)
  2453. y = np.exp(-x)
  2454. yerr1 = 0.1 + 0.2*np.sqrt(x)
  2455. yerr = np.vstack((yerr1, 2*yerr1)).T
  2456. xerr = 0.1 + yerr
  2457. with pytest.raises(ValueError):
  2458. ax.errorbar(x, y, yerr=yerr, fmt='o')
  2459. with pytest.raises(ValueError):
  2460. ax.errorbar(x, y, xerr=xerr, fmt='o')
  2461. with pytest.raises(ValueError):
  2462. ax.errorbar(x, y, yerr=yerr, xerr=xerr, fmt='o')
  2463. @image_comparison(['errorbar_limits'])
  2464. def test_errorbar_limits():
  2465. x = np.arange(0.5, 5.5, 0.5)
  2466. y = np.exp(-x)
  2467. xerr = 0.1
  2468. yerr = 0.2
  2469. ls = 'dotted'
  2470. fig = plt.figure()
  2471. ax = fig.add_subplot(1, 1, 1)
  2472. # standard error bars
  2473. plt.errorbar(x, y, xerr=xerr, yerr=yerr, ls=ls, color='blue')
  2474. # including upper limits
  2475. uplims = np.zeros_like(x)
  2476. uplims[[1, 5, 9]] = True
  2477. plt.errorbar(x, y+0.5, xerr=xerr, yerr=yerr, uplims=uplims, ls=ls,
  2478. color='green')
  2479. # including lower limits
  2480. lolims = np.zeros_like(x)
  2481. lolims[[2, 4, 8]] = True
  2482. plt.errorbar(x, y+1.0, xerr=xerr, yerr=yerr, lolims=lolims, ls=ls,
  2483. color='red')
  2484. # including upper and lower limits
  2485. plt.errorbar(x, y+1.5, marker='o', ms=8, xerr=xerr, yerr=yerr,
  2486. lolims=lolims, uplims=uplims, ls=ls, color='magenta')
  2487. # including xlower and xupper limits
  2488. xerr = 0.2
  2489. yerr = np.full_like(x, 0.2)
  2490. yerr[[3, 6]] = 0.3
  2491. xlolims = lolims
  2492. xuplims = uplims
  2493. lolims = np.zeros_like(x)
  2494. uplims = np.zeros_like(x)
  2495. lolims[[6]] = True
  2496. uplims[[3]] = True
  2497. plt.errorbar(x, y+2.1, marker='o', ms=8, xerr=xerr, yerr=yerr,
  2498. xlolims=xlolims, xuplims=xuplims, uplims=uplims,
  2499. lolims=lolims, ls='none', mec='blue', capsize=0,
  2500. color='cyan')
  2501. ax.set_xlim((0, 5.5))
  2502. ax.set_title('Errorbar upper and lower limits')
  2503. def test_errobar_nonefmt():
  2504. # Check that passing 'none' as a format still plots errorbars
  2505. x = np.arange(5)
  2506. y = np.arange(5)
  2507. plotline, _, barlines = plt.errorbar(x, y, xerr=1, yerr=1, fmt='none')
  2508. assert plotline is None
  2509. for errbar in barlines:
  2510. assert np.all(errbar.get_color() == mcolors.to_rgba('C0'))
  2511. @image_comparison(['errorbar_with_prop_cycle.png'],
  2512. style='mpl20', remove_text=True)
  2513. def test_errorbar_with_prop_cycle():
  2514. _cycle = cycler(ls=['--', ':'], marker=['s', 's'], mfc=['k', 'w'])
  2515. plt.rc("axes", prop_cycle=_cycle)
  2516. fig, ax = plt.subplots()
  2517. ax.errorbar(x=[2, 4, 10], y=[3, 2, 4], yerr=0.5)
  2518. ax.errorbar(x=[2, 4, 10], y=[6, 4, 2], yerr=0.5)
  2519. @check_figures_equal()
  2520. def test_errorbar_offsets(fig_test, fig_ref):
  2521. x = np.linspace(0, 1, 15)
  2522. y = x * (1-x)
  2523. yerr = y/6
  2524. ax_ref = fig_ref.subplots()
  2525. ax_test = fig_test.subplots()
  2526. for color, shift in zip('rgbk', [0, 0, 2, 7]):
  2527. y += .02
  2528. # Using feature in question
  2529. ax_test.errorbar(x, y, yerr, errorevery=(shift, 4),
  2530. capsize=4, c=color)
  2531. # Using manual errorbars
  2532. # n.b. errorbar draws the main plot at z=2.1 by default
  2533. ax_ref.plot(x, y, c=color, zorder=2.1)
  2534. ax_ref.errorbar(x[shift::4], y[shift::4], yerr[shift::4],
  2535. capsize=4, c=color, fmt='none')
  2536. @image_comparison(['hist_stacked_stepfilled', 'hist_stacked_stepfilled'])
  2537. def test_hist_stacked_stepfilled():
  2538. # make some data
  2539. d1 = np.linspace(1, 3, 20)
  2540. d2 = np.linspace(0, 10, 50)
  2541. fig = plt.figure()
  2542. ax = fig.add_subplot(111)
  2543. ax.hist((d1, d2), histtype="stepfilled", stacked=True)
  2544. # Reuse testcase from above for a labeled data test
  2545. data = {"x": (d1, d2)}
  2546. fig = plt.figure()
  2547. ax = fig.add_subplot(111)
  2548. ax.hist("x", histtype="stepfilled", stacked=True, data=data)
  2549. @image_comparison(['hist_offset'])
  2550. def test_hist_offset():
  2551. # make some data
  2552. d1 = np.linspace(0, 10, 50)
  2553. d2 = np.linspace(1, 3, 20)
  2554. fig = plt.figure()
  2555. ax = fig.add_subplot(111)
  2556. ax.hist(d1, bottom=5)
  2557. ax.hist(d2, bottom=15)
  2558. @image_comparison(['hist_step.png'], remove_text=True)
  2559. def test_hist_step():
  2560. # make some data
  2561. d1 = np.linspace(1, 3, 20)
  2562. fig = plt.figure()
  2563. ax = fig.add_subplot(111)
  2564. ax.hist(d1, histtype="step")
  2565. ax.set_ylim(0, 10)
  2566. ax.set_xlim(-1, 5)
  2567. @image_comparison(['hist_step_horiz.png'])
  2568. def test_hist_step_horiz():
  2569. # make some data
  2570. d1 = np.linspace(0, 10, 50)
  2571. d2 = np.linspace(1, 3, 20)
  2572. fig = plt.figure()
  2573. ax = fig.add_subplot(111)
  2574. ax.hist((d1, d2), histtype="step", orientation="horizontal")
  2575. @image_comparison(['hist_stacked_weights'])
  2576. def test_hist_stacked_weighted():
  2577. # make some data
  2578. d1 = np.linspace(0, 10, 50)
  2579. d2 = np.linspace(1, 3, 20)
  2580. w1 = np.linspace(0.01, 3.5, 50)
  2581. w2 = np.linspace(0.05, 2., 20)
  2582. fig = plt.figure()
  2583. ax = fig.add_subplot(111)
  2584. ax.hist((d1, d2), weights=(w1, w2), histtype="stepfilled", stacked=True)
  2585. @image_comparison(['stem.png', 'stem.png'], style='mpl20', remove_text=True)
  2586. def test_stem():
  2587. # Note, we don't use @pytest.mark.parametrize, because in parallel this
  2588. # might cause one process result to overwrite another's.
  2589. for use_line_collection in [True, False]:
  2590. _test_stem(use_line_collection)
  2591. def _test_stem(use_line_collection):
  2592. x = np.linspace(0.1, 2 * np.pi, 100)
  2593. args = (x, np.cos(x))
  2594. # Label is a single space to force a legend to be drawn, but to avoid any
  2595. # text being drawn
  2596. kwargs = dict(linefmt='C2-.', markerfmt='k+', basefmt='C1-.',
  2597. label=' ', use_line_collection=use_line_collection)
  2598. fig, ax = plt.subplots()
  2599. if use_line_collection:
  2600. ax.stem(*args, **kwargs)
  2601. else:
  2602. with pytest.warns(UserWarning):
  2603. ax.stem(*args, **kwargs)
  2604. ax.legend()
  2605. @check_figures_equal(extensions=['png'])
  2606. def test_stem_params(fig_test, fig_ref):
  2607. x = np.linspace(0, 3.14, 37)
  2608. y = np.sin(x)
  2609. ax = fig_test.subplots()
  2610. ax.stem(x, y, linefmt='grey', use_line_collection=True)
  2611. ax = fig_ref.subplots()
  2612. with pytest.warns(UserWarning):
  2613. ax.stem(x, y, linefmt='grey')
  2614. def test_stem_args():
  2615. fig = plt.figure()
  2616. ax = fig.add_subplot(1, 1, 1)
  2617. x = list(range(10))
  2618. y = list(range(10))
  2619. # Test the call signatures
  2620. ax.stem(y, use_line_collection=True)
  2621. ax.stem(x, y, use_line_collection=True)
  2622. ax.stem(x, y, 'r--', use_line_collection=True)
  2623. ax.stem(x, y, 'r--', basefmt='b--', use_line_collection=True)
  2624. def test_stem_dates():
  2625. fig, ax = plt.subplots(1, 1)
  2626. from dateutil import parser
  2627. x = parser.parse("2013-9-28 11:00:00")
  2628. y = 100
  2629. x1 = parser.parse("2013-9-28 12:00:00")
  2630. y1 = 200
  2631. ax.stem([x, x1], [y, y1], "*-", use_line_collection=True)
  2632. @image_comparison(['hist_stacked_stepfilled_alpha'])
  2633. def test_hist_stacked_stepfilled_alpha():
  2634. # make some data
  2635. d1 = np.linspace(1, 3, 20)
  2636. d2 = np.linspace(0, 10, 50)
  2637. fig = plt.figure()
  2638. ax = fig.add_subplot(111)
  2639. ax.hist((d1, d2), histtype="stepfilled", stacked=True, alpha=0.5)
  2640. @image_comparison(['hist_stacked_step'])
  2641. def test_hist_stacked_step():
  2642. # make some data
  2643. d1 = np.linspace(1, 3, 20)
  2644. d2 = np.linspace(0, 10, 50)
  2645. fig = plt.figure()
  2646. ax = fig.add_subplot(111)
  2647. ax.hist((d1, d2), histtype="step", stacked=True)
  2648. @image_comparison(['hist_stacked_normed'])
  2649. def test_hist_stacked_density():
  2650. # make some data
  2651. d1 = np.linspace(1, 3, 20)
  2652. d2 = np.linspace(0, 10, 50)
  2653. fig, ax = plt.subplots()
  2654. ax.hist((d1, d2), stacked=True, density=True)
  2655. @image_comparison(['hist_step_bottom.png'], remove_text=True)
  2656. def test_hist_step_bottom():
  2657. # make some data
  2658. d1 = np.linspace(1, 3, 20)
  2659. fig = plt.figure()
  2660. ax = fig.add_subplot(111)
  2661. ax.hist(d1, bottom=np.arange(10), histtype="stepfilled")
  2662. @image_comparison(['hist_stacked_bar'])
  2663. def test_hist_stacked_bar():
  2664. # make some data
  2665. d = [[100, 100, 100, 100, 200, 320, 450, 80, 20, 600, 310, 800],
  2666. [20, 23, 50, 11, 100, 420], [120, 120, 120, 140, 140, 150, 180],
  2667. [60, 60, 60, 60, 300, 300, 5, 5, 5, 5, 10, 300],
  2668. [555, 555, 555, 30, 30, 30, 30, 30, 100, 100, 100, 100, 30, 30],
  2669. [30, 30, 30, 30, 400, 400, 400, 400, 400, 400, 400, 400]]
  2670. colors = [(0.5759849696758961, 1.0, 0.0), (0.0, 1.0, 0.350624650815206),
  2671. (0.0, 1.0, 0.6549834156005998), (0.0, 0.6569064625276622, 1.0),
  2672. (0.28302699607823545, 0.0, 1.0), (0.6849123462299822, 0.0, 1.0)]
  2673. labels = ['green', 'orange', ' yellow', 'magenta', 'black']
  2674. fig = plt.figure()
  2675. ax = fig.add_subplot(111)
  2676. ax.hist(d, bins=10, histtype='barstacked', align='mid', color=colors,
  2677. label=labels)
  2678. ax.legend(loc='upper right', bbox_to_anchor=(1.0, 1.0), ncol=1)
  2679. def test_hist_emptydata():
  2680. fig = plt.figure()
  2681. ax = fig.add_subplot(111)
  2682. ax.hist([[], range(10), range(10)], histtype="step")
  2683. def test_hist_labels():
  2684. # test singleton labels OK
  2685. fig, ax = plt.subplots()
  2686. l = ax.hist([0, 1], label=0)
  2687. assert l[2][0].get_label() == '0'
  2688. l = ax.hist([0, 1], label=[0])
  2689. assert l[2][0].get_label() == '0'
  2690. l = ax.hist([0, 1], label=None)
  2691. assert l[2][0].get_label() == '_nolegend_'
  2692. l = ax.hist([0, 1], label='0')
  2693. assert l[2][0].get_label() == '0'
  2694. l = ax.hist([0, 1], label='00')
  2695. assert l[2][0].get_label() == '00'
  2696. @image_comparison(['transparent_markers'], remove_text=True)
  2697. def test_transparent_markers():
  2698. np.random.seed(0)
  2699. data = np.random.random(50)
  2700. fig = plt.figure()
  2701. ax = fig.add_subplot(111)
  2702. ax.plot(data, 'D', mfc='none', markersize=100)
  2703. @image_comparison(['rgba_markers'], remove_text=True)
  2704. def test_rgba_markers():
  2705. fig, axs = plt.subplots(ncols=2)
  2706. rcolors = [(1, 0, 0, 1), (1, 0, 0, 0.5)]
  2707. bcolors = [(0, 0, 1, 1), (0, 0, 1, 0.5)]
  2708. alphas = [None, 0.2]
  2709. kw = dict(ms=100, mew=20)
  2710. for i, alpha in enumerate(alphas):
  2711. for j, rcolor in enumerate(rcolors):
  2712. for k, bcolor in enumerate(bcolors):
  2713. axs[i].plot(j+1, k+1, 'o', mfc=bcolor, mec=rcolor,
  2714. alpha=alpha, **kw)
  2715. axs[i].plot(j+1, k+3, 'x', mec=rcolor, alpha=alpha, **kw)
  2716. for ax in axs:
  2717. ax.axis([-1, 4, 0, 5])
  2718. @image_comparison(['mollweide_grid'], remove_text=True)
  2719. def test_mollweide_grid():
  2720. # test that both horizontal and vertical gridlines appear on the Mollweide
  2721. # projection
  2722. fig = plt.figure()
  2723. ax = fig.add_subplot(111, projection='mollweide')
  2724. ax.grid()
  2725. def test_mollweide_forward_inverse_closure():
  2726. # test that the round-trip Mollweide forward->inverse transformation is an
  2727. # approximate identity
  2728. fig = plt.figure()
  2729. ax = fig.add_subplot(111, projection='mollweide')
  2730. # set up 1-degree grid in longitude, latitude
  2731. lon = np.linspace(-np.pi, np.pi, 360)
  2732. lat = np.linspace(-np.pi / 2.0, np.pi / 2.0, 180)
  2733. lon, lat = np.meshgrid(lon, lat)
  2734. ll = np.vstack((lon.flatten(), lat.flatten())).T
  2735. # perform forward transform
  2736. xy = ax.transProjection.transform(ll)
  2737. # perform inverse transform
  2738. ll2 = ax.transProjection.inverted().transform(xy)
  2739. # compare
  2740. np.testing.assert_array_almost_equal(ll, ll2, 3)
  2741. def test_mollweide_inverse_forward_closure():
  2742. # test that the round-trip Mollweide inverse->forward transformation is an
  2743. # approximate identity
  2744. fig = plt.figure()
  2745. ax = fig.add_subplot(111, projection='mollweide')
  2746. # set up grid in x, y
  2747. x = np.linspace(0, 1, 500)
  2748. x, y = np.meshgrid(x, x)
  2749. xy = np.vstack((x.flatten(), y.flatten())).T
  2750. # perform inverse transform
  2751. ll = ax.transProjection.inverted().transform(xy)
  2752. # perform forward transform
  2753. xy2 = ax.transProjection.transform(ll)
  2754. # compare
  2755. np.testing.assert_array_almost_equal(xy, xy2, 3)
  2756. @image_comparison(['test_alpha'], remove_text=True)
  2757. def test_alpha():
  2758. np.random.seed(0)
  2759. data = np.random.random(50)
  2760. fig = plt.figure()
  2761. ax = fig.add_subplot(111)
  2762. # alpha=.5 markers, solid line
  2763. ax.plot(data, '-D', color=[1, 0, 0], mfc=[1, 0, 0, .5],
  2764. markersize=20, lw=10)
  2765. # everything solid by kwarg
  2766. ax.plot(data + 2, '-D', color=[1, 0, 0, .5], mfc=[1, 0, 0, .5],
  2767. markersize=20, lw=10,
  2768. alpha=1)
  2769. # everything alpha=.5 by kwarg
  2770. ax.plot(data + 4, '-D', color=[1, 0, 0], mfc=[1, 0, 0],
  2771. markersize=20, lw=10,
  2772. alpha=.5)
  2773. # everything alpha=.5 by colors
  2774. ax.plot(data + 6, '-D', color=[1, 0, 0, .5], mfc=[1, 0, 0, .5],
  2775. markersize=20, lw=10)
  2776. # alpha=.5 line, solid markers
  2777. ax.plot(data + 8, '-D', color=[1, 0, 0, .5], mfc=[1, 0, 0],
  2778. markersize=20, lw=10)
  2779. @image_comparison(['eventplot', 'eventplot'], remove_text=True)
  2780. def test_eventplot():
  2781. '''
  2782. test that eventplot produces the correct output
  2783. '''
  2784. np.random.seed(0)
  2785. data1 = np.random.random([32, 20]).tolist()
  2786. data2 = np.random.random([6, 20]).tolist()
  2787. data = data1 + data2
  2788. num_datasets = len(data)
  2789. colors1 = [[0, 1, .7]] * len(data1)
  2790. colors2 = [[1, 0, 0],
  2791. [0, 1, 0],
  2792. [0, 0, 1],
  2793. [1, .75, 0],
  2794. [1, 0, 1],
  2795. [0, 1, 1]]
  2796. colors = colors1 + colors2
  2797. lineoffsets1 = 12 + np.arange(0, len(data1)) * .33
  2798. lineoffsets2 = [-15, -3, 1, 1.5, 6, 10]
  2799. lineoffsets = lineoffsets1.tolist() + lineoffsets2
  2800. linelengths1 = [.33] * len(data1)
  2801. linelengths2 = [5, 2, 1, 1, 3, 1.5]
  2802. linelengths = linelengths1 + linelengths2
  2803. fig = plt.figure()
  2804. axobj = fig.add_subplot(111)
  2805. colls = axobj.eventplot(data, colors=colors, lineoffsets=lineoffsets,
  2806. linelengths=linelengths)
  2807. num_collections = len(colls)
  2808. assert num_collections == num_datasets
  2809. # Reuse testcase from above for a labeled data test
  2810. data = {"pos": data, "c": colors, "lo": lineoffsets, "ll": linelengths}
  2811. fig = plt.figure()
  2812. axobj = fig.add_subplot(111)
  2813. colls = axobj.eventplot("pos", colors="c", lineoffsets="lo",
  2814. linelengths="ll", data=data)
  2815. num_collections = len(colls)
  2816. assert num_collections == num_datasets
  2817. @image_comparison(['test_eventplot_defaults.png'], remove_text=True)
  2818. def test_eventplot_defaults():
  2819. '''
  2820. test that eventplot produces the correct output given the default params
  2821. (see bug #3728)
  2822. '''
  2823. np.random.seed(0)
  2824. data1 = np.random.random([32, 20]).tolist()
  2825. data2 = np.random.random([6, 20]).tolist()
  2826. data = data1 + data2
  2827. fig = plt.figure()
  2828. axobj = fig.add_subplot(111)
  2829. axobj.eventplot(data)
  2830. @pytest.mark.parametrize(('colors'), [
  2831. ('0.5',), # string color with multiple characters: not OK before #8193 fix
  2832. ('tab:orange', 'tab:pink', 'tab:cyan', 'bLacK'), # case-insensitive
  2833. ('red', (0, 1, 0), None, (1, 0, 1, 0.5)), # a tricky case mixing types
  2834. ])
  2835. def test_eventplot_colors(colors):
  2836. '''Test the *colors* parameter of eventplot. Inspired by the issue #8193.
  2837. '''
  2838. data = [[i] for i in range(4)] # 4 successive events of different nature
  2839. # Build the list of the expected colors
  2840. expected = [c if c is not None else 'C0' for c in colors]
  2841. # Convert the list into an array of RGBA values
  2842. # NB: ['rgbk'] is not a valid argument for to_rgba_array, while 'rgbk' is.
  2843. if len(expected) == 1:
  2844. expected = expected[0]
  2845. expected = np.broadcast_to(mcolors.to_rgba_array(expected), (len(data), 4))
  2846. fig, ax = plt.subplots()
  2847. if len(colors) == 1: # tuple with a single string (like '0.5' or 'rgbk')
  2848. colors = colors[0]
  2849. collections = ax.eventplot(data, colors=colors)
  2850. for coll, color in zip(collections, expected):
  2851. assert_allclose(coll.get_color(), color)
  2852. @image_comparison(['test_eventplot_problem_kwargs.png'], remove_text=True)
  2853. def test_eventplot_problem_kwargs():
  2854. '''
  2855. test that 'singular' versions of LineCollection props raise an
  2856. IgnoredKeywordWarning rather than overriding the 'plural' versions (e.g.
  2857. to prevent 'color' from overriding 'colors', see issue #4297)
  2858. '''
  2859. np.random.seed(0)
  2860. data1 = np.random.random([20]).tolist()
  2861. data2 = np.random.random([10]).tolist()
  2862. data = [data1, data2]
  2863. fig = plt.figure()
  2864. axobj = fig.add_subplot(111)
  2865. with warnings.catch_warnings(record=True) as w:
  2866. warnings.simplefilter("always")
  2867. axobj.eventplot(data,
  2868. colors=['r', 'b'],
  2869. color=['c', 'm'],
  2870. linewidths=[2, 1],
  2871. linewidth=[1, 2],
  2872. linestyles=['solid', 'dashed'],
  2873. linestyle=['dashdot', 'dotted'])
  2874. # check that three IgnoredKeywordWarnings were raised
  2875. assert len(w) == 3
  2876. assert all(issubclass(wi.category, IgnoredKeywordWarning) for wi in w)
  2877. def test_empty_eventplot():
  2878. fig, ax = plt.subplots(1, 1)
  2879. ax.eventplot([[]], colors=[(0.0, 0.0, 0.0, 0.0)])
  2880. plt.draw()
  2881. @pytest.mark.parametrize('data, orientation', product(
  2882. ([[]], [[], [0, 1]], [[0, 1], []]),
  2883. ('_empty', 'vertical', 'horizontal', None, 'none')))
  2884. def test_eventplot_orientation(data, orientation):
  2885. """Introduced when fixing issue #6412."""
  2886. opts = {} if orientation == "_empty" else {'orientation': orientation}
  2887. fig, ax = plt.subplots(1, 1)
  2888. ax.eventplot(data, **opts)
  2889. plt.draw()
  2890. @image_comparison(['marker_styles.png'], remove_text=True)
  2891. def test_marker_styles():
  2892. fig = plt.figure()
  2893. ax = fig.add_subplot(111)
  2894. for y, marker in enumerate(sorted(matplotlib.markers.MarkerStyle.markers,
  2895. key=lambda x: str(type(x))+str(x))):
  2896. ax.plot((y % 2)*5 + np.arange(10)*10, np.ones(10)*10*y, linestyle='',
  2897. marker=marker, markersize=10+y/5, label=marker)
  2898. @image_comparison(['rc_markerfill.png'])
  2899. def test_markers_fillstyle_rcparams():
  2900. fig, ax = plt.subplots()
  2901. x = np.arange(7)
  2902. for idx, (style, marker) in enumerate(
  2903. [('top', 's'), ('bottom', 'o'), ('none', '^')]):
  2904. matplotlib.rcParams['markers.fillstyle'] = style
  2905. ax.plot(x+idx, marker=marker)
  2906. @image_comparison(['vertex_markers.png'], remove_text=True)
  2907. def test_vertex_markers():
  2908. data = list(range(10))
  2909. marker_as_tuple = ((-1, -1), (1, -1), (1, 1), (-1, 1))
  2910. marker_as_list = [(-1, -1), (1, -1), (1, 1), (-1, 1)]
  2911. fig = plt.figure()
  2912. ax = fig.add_subplot(111)
  2913. ax.plot(data, linestyle='', marker=marker_as_tuple, mfc='k')
  2914. ax.plot(data[::-1], linestyle='', marker=marker_as_list, mfc='b')
  2915. ax.set_xlim([-1, 10])
  2916. ax.set_ylim([-1, 10])
  2917. @image_comparison(['vline_hline_zorder', 'errorbar_zorder'],
  2918. tol={'aarch64': 0.02}.get(platform.machine(), 0.0))
  2919. def test_eb_line_zorder():
  2920. x = list(range(10))
  2921. # First illustrate basic pyplot interface, using defaults where possible.
  2922. fig = plt.figure()
  2923. ax = fig.gca()
  2924. ax.plot(x, lw=10, zorder=5)
  2925. ax.axhline(1, color='red', lw=10, zorder=1)
  2926. ax.axhline(5, color='green', lw=10, zorder=10)
  2927. ax.axvline(7, color='m', lw=10, zorder=7)
  2928. ax.axvline(2, color='k', lw=10, zorder=3)
  2929. ax.set_title("axvline and axhline zorder test")
  2930. # Now switch to a more OO interface to exercise more features.
  2931. fig = plt.figure()
  2932. ax = fig.gca()
  2933. x = list(range(10))
  2934. y = np.zeros(10)
  2935. yerr = list(range(10))
  2936. ax.errorbar(x, y, yerr=yerr, zorder=5, lw=5, color='r')
  2937. for j in range(10):
  2938. ax.axhline(j, lw=5, color='k', zorder=j)
  2939. ax.axhline(-j, lw=5, color='k', zorder=j)
  2940. ax.set_title("errorbar zorder test")
  2941. @image_comparison(['vlines_basic', 'vlines_with_nan', 'vlines_masked'],
  2942. extensions=['png'])
  2943. def test_vlines():
  2944. # normal
  2945. x1 = [2, 3, 4, 5, 7]
  2946. y1 = [2, -6, 3, 8, 2]
  2947. fig1, ax1 = plt.subplots()
  2948. ax1.vlines(x1, 0, y1, colors='g', linewidth=5)
  2949. # GH #7406
  2950. x2 = [2, 3, 4, 5, 6, 7]
  2951. y2 = [2, -6, 3, 8, np.nan, 2]
  2952. fig2, (ax2, ax3, ax4) = plt.subplots(nrows=3, figsize=(4, 8))
  2953. ax2.vlines(x2, 0, y2, colors='g', linewidth=5)
  2954. x3 = [2, 3, 4, 5, 6, 7]
  2955. y3 = [np.nan, 2, -6, 3, 8, 2]
  2956. ax3.vlines(x3, 0, y3, colors='r', linewidth=3, linestyle='--')
  2957. x4 = [2, 3, 4, 5, 6, 7]
  2958. y4 = [np.nan, 2, -6, 3, 8, np.nan]
  2959. ax4.vlines(x4, 0, y4, colors='k', linewidth=2)
  2960. # tweak the x-axis so we can see the lines better
  2961. for ax in [ax1, ax2, ax3, ax4]:
  2962. ax.set_xlim(0, 10)
  2963. # check that the y-lims are all automatically the same
  2964. assert ax1.get_ylim() == ax2.get_ylim()
  2965. assert ax1.get_ylim() == ax3.get_ylim()
  2966. assert ax1.get_ylim() == ax4.get_ylim()
  2967. fig3, ax5 = plt.subplots()
  2968. x5 = np.ma.masked_equal([2, 4, 6, 8, 10, 12], 8)
  2969. ymin5 = np.ma.masked_equal([0, 1, -1, 0, 2, 1], 2)
  2970. ymax5 = np.ma.masked_equal([13, 14, 15, 16, 17, 18], 18)
  2971. ax5.vlines(x5, ymin5, ymax5, colors='k', linewidth=2)
  2972. ax5.set_xlim(0, 15)
  2973. @image_comparison(['hlines_basic', 'hlines_with_nan', 'hlines_masked'],
  2974. extensions=['png'])
  2975. def test_hlines():
  2976. # normal
  2977. y1 = [2, 3, 4, 5, 7]
  2978. x1 = [2, -6, 3, 8, 2]
  2979. fig1, ax1 = plt.subplots()
  2980. ax1.hlines(y1, 0, x1, colors='g', linewidth=5)
  2981. # GH #7406
  2982. y2 = [2, 3, 4, 5, 6, 7]
  2983. x2 = [2, -6, 3, 8, np.nan, 2]
  2984. fig2, (ax2, ax3, ax4) = plt.subplots(nrows=3, figsize=(4, 8))
  2985. ax2.hlines(y2, 0, x2, colors='g', linewidth=5)
  2986. y3 = [2, 3, 4, 5, 6, 7]
  2987. x3 = [np.nan, 2, -6, 3, 8, 2]
  2988. ax3.hlines(y3, 0, x3, colors='r', linewidth=3, linestyle='--')
  2989. y4 = [2, 3, 4, 5, 6, 7]
  2990. x4 = [np.nan, 2, -6, 3, 8, np.nan]
  2991. ax4.hlines(y4, 0, x4, colors='k', linewidth=2)
  2992. # tweak the y-axis so we can see the lines better
  2993. for ax in [ax1, ax2, ax3, ax4]:
  2994. ax.set_ylim(0, 10)
  2995. # check that the x-lims are all automatically the same
  2996. assert ax1.get_xlim() == ax2.get_xlim()
  2997. assert ax1.get_xlim() == ax3.get_xlim()
  2998. assert ax1.get_xlim() == ax4.get_xlim()
  2999. fig3, ax5 = plt.subplots()
  3000. y5 = np.ma.masked_equal([2, 4, 6, 8, 10, 12], 8)
  3001. xmin5 = np.ma.masked_equal([0, 1, -1, 0, 2, 1], 2)
  3002. xmax5 = np.ma.masked_equal([13, 14, 15, 16, 17, 18], 18)
  3003. ax5.hlines(y5, xmin5, xmax5, colors='k', linewidth=2)
  3004. ax5.set_ylim(0, 15)
  3005. @image_comparison(['step_linestyle', 'step_linestyle'], remove_text=True)
  3006. def test_step_linestyle():
  3007. x = y = np.arange(10)
  3008. # First illustrate basic pyplot interface, using defaults where possible.
  3009. fig, ax_lst = plt.subplots(2, 2)
  3010. ax_lst = ax_lst.flatten()
  3011. ln_styles = ['-', '--', '-.', ':']
  3012. for ax, ls in zip(ax_lst, ln_styles):
  3013. ax.step(x, y, lw=5, linestyle=ls, where='pre')
  3014. ax.step(x, y + 1, lw=5, linestyle=ls, where='mid')
  3015. ax.step(x, y + 2, lw=5, linestyle=ls, where='post')
  3016. ax.set_xlim([-1, 5])
  3017. ax.set_ylim([-1, 7])
  3018. # Reuse testcase from above for a labeled data test
  3019. data = {"X": x, "Y0": y, "Y1": y+1, "Y2": y+2}
  3020. fig, ax_lst = plt.subplots(2, 2)
  3021. ax_lst = ax_lst.flatten()
  3022. ln_styles = ['-', '--', '-.', ':']
  3023. for ax, ls in zip(ax_lst, ln_styles):
  3024. ax.step("X", "Y0", lw=5, linestyle=ls, where='pre', data=data)
  3025. ax.step("X", "Y1", lw=5, linestyle=ls, where='mid', data=data)
  3026. ax.step("X", "Y2", lw=5, linestyle=ls, where='post', data=data)
  3027. ax.set_xlim([-1, 5])
  3028. ax.set_ylim([-1, 7])
  3029. @image_comparison(['mixed_collection'], remove_text=True)
  3030. def test_mixed_collection():
  3031. from matplotlib import patches
  3032. from matplotlib import collections
  3033. # First illustrate basic pyplot interface, using defaults where possible.
  3034. fig = plt.figure()
  3035. ax = fig.add_subplot(1, 1, 1)
  3036. c = patches.Circle((8, 8), radius=4, facecolor='none', edgecolor='green')
  3037. # PDF can optimize this one
  3038. p1 = collections.PatchCollection([c], match_original=True)
  3039. p1.set_offsets([[0, 0], [24, 24]])
  3040. p1.set_linewidths([1, 5])
  3041. # PDF can't optimize this one, because the alpha of the edge changes
  3042. p2 = collections.PatchCollection([c], match_original=True)
  3043. p2.set_offsets([[48, 0], [-32, -16]])
  3044. p2.set_linewidths([1, 5])
  3045. p2.set_edgecolors([[0, 0, 0.1, 1.0], [0, 0, 0.1, 0.5]])
  3046. ax.patch.set_color('0.5')
  3047. ax.add_collection(p1)
  3048. ax.add_collection(p2)
  3049. ax.set_xlim(0, 16)
  3050. ax.set_ylim(0, 16)
  3051. def test_subplot_key_hash():
  3052. ax = plt.subplot(np.float64(5.5), np.int64(1), np.float64(1.2))
  3053. ax.twinx()
  3054. assert ax.get_subplotspec().get_geometry() == (5, 1, 0, 0)
  3055. @image_comparison(['specgram_freqs.png', 'specgram_freqs_linear.png'],
  3056. remove_text=True, tol=0.07, style='default')
  3057. def test_specgram_freqs():
  3058. '''test axes.specgram in default (psd) mode with sinusoidal stimuli'''
  3059. # use former defaults to match existing baseline image
  3060. matplotlib.rcParams['image.interpolation'] = 'nearest'
  3061. n = 1000
  3062. Fs = 10.
  3063. fstims1 = [Fs/4, Fs/5, Fs/11]
  3064. fstims2 = [Fs/4.7, Fs/5.6, Fs/11.9]
  3065. NFFT = int(10 * Fs / min(fstims1 + fstims2))
  3066. noverlap = int(NFFT / 2)
  3067. pad_to = int(2 ** np.ceil(np.log2(NFFT)))
  3068. x = np.arange(0, n, 1/Fs)
  3069. y1 = np.zeros(x.size)
  3070. y2 = np.zeros(x.size)
  3071. for fstim1, fstim2 in zip(fstims1, fstims2):
  3072. y1 += np.sin(fstim1 * x * np.pi * 2)
  3073. y2 += np.sin(fstim2 * x * np.pi * 2)
  3074. y = np.hstack([y1, y2])
  3075. fig1 = plt.figure()
  3076. fig2 = plt.figure()
  3077. ax11 = fig1.add_subplot(3, 1, 1)
  3078. ax12 = fig1.add_subplot(3, 1, 2)
  3079. ax13 = fig1.add_subplot(3, 1, 3)
  3080. ax21 = fig2.add_subplot(3, 1, 1)
  3081. ax22 = fig2.add_subplot(3, 1, 2)
  3082. ax23 = fig2.add_subplot(3, 1, 3)
  3083. ax11.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3084. pad_to=pad_to, sides='default')
  3085. ax12.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3086. pad_to=pad_to, sides='onesided')
  3087. ax13.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3088. pad_to=pad_to, sides='twosided')
  3089. ax21.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3090. pad_to=pad_to, sides='default',
  3091. scale='linear', norm=matplotlib.colors.LogNorm())
  3092. ax22.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3093. pad_to=pad_to, sides='onesided',
  3094. scale='linear', norm=matplotlib.colors.LogNorm())
  3095. ax23.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3096. pad_to=pad_to, sides='twosided',
  3097. scale='linear', norm=matplotlib.colors.LogNorm())
  3098. @image_comparison(['specgram_noise.png', 'specgram_noise_linear.png'],
  3099. remove_text=True, tol=0.01, style='default')
  3100. def test_specgram_noise():
  3101. '''test axes.specgram in default (psd) mode with noise stimuli'''
  3102. # use former defaults to match existing baseline image
  3103. matplotlib.rcParams['image.interpolation'] = 'nearest'
  3104. np.random.seed(0)
  3105. n = 1000
  3106. Fs = 10.
  3107. NFFT = int(10 * Fs / 11)
  3108. noverlap = int(NFFT / 2)
  3109. pad_to = int(2 ** np.ceil(np.log2(NFFT)))
  3110. y1 = np.random.standard_normal(n)
  3111. y2 = np.random.rand(n)
  3112. y = np.hstack([y1, y2])
  3113. fig1 = plt.figure()
  3114. fig2 = plt.figure()
  3115. ax11 = fig1.add_subplot(3, 1, 1)
  3116. ax12 = fig1.add_subplot(3, 1, 2)
  3117. ax13 = fig1.add_subplot(3, 1, 3)
  3118. ax21 = fig2.add_subplot(3, 1, 1)
  3119. ax22 = fig2.add_subplot(3, 1, 2)
  3120. ax23 = fig2.add_subplot(3, 1, 3)
  3121. ax11.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3122. pad_to=pad_to, sides='default')
  3123. ax12.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3124. pad_to=pad_to, sides='onesided')
  3125. ax13.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3126. pad_to=pad_to, sides='twosided')
  3127. ax21.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3128. pad_to=pad_to, sides='default',
  3129. scale='linear', norm=matplotlib.colors.LogNorm())
  3130. ax22.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3131. pad_to=pad_to, sides='onesided',
  3132. scale='linear', norm=matplotlib.colors.LogNorm())
  3133. ax23.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3134. pad_to=pad_to, sides='twosided',
  3135. scale='linear', norm=matplotlib.colors.LogNorm())
  3136. @image_comparison(['specgram_magnitude_freqs.png',
  3137. 'specgram_magnitude_freqs_linear.png'],
  3138. remove_text=True, tol=0.07, style='default')
  3139. def test_specgram_magnitude_freqs():
  3140. '''test axes.specgram in magnitude mode with sinusoidal stimuli'''
  3141. # use former defaults to match existing baseline image
  3142. matplotlib.rcParams['image.interpolation'] = 'nearest'
  3143. n = 1000
  3144. Fs = 10.
  3145. fstims1 = [Fs/4, Fs/5, Fs/11]
  3146. fstims2 = [Fs/4.7, Fs/5.6, Fs/11.9]
  3147. NFFT = int(100 * Fs / min(fstims1 + fstims2))
  3148. noverlap = int(NFFT / 2)
  3149. pad_to = int(2 ** np.ceil(np.log2(NFFT)))
  3150. x = np.arange(0, n, 1/Fs)
  3151. y1 = np.zeros(x.size)
  3152. y2 = np.zeros(x.size)
  3153. for i, (fstim1, fstim2) in enumerate(zip(fstims1, fstims2)):
  3154. y1 += np.sin(fstim1 * x * np.pi * 2)
  3155. y2 += np.sin(fstim2 * x * np.pi * 2)
  3156. y1[-1] = y1[-1]/y1[-1]
  3157. y2[-1] = y2[-1]/y2[-1]
  3158. y = np.hstack([y1, y2])
  3159. fig1 = plt.figure()
  3160. fig2 = plt.figure()
  3161. ax11 = fig1.add_subplot(3, 1, 1)
  3162. ax12 = fig1.add_subplot(3, 1, 2)
  3163. ax13 = fig1.add_subplot(3, 1, 3)
  3164. ax21 = fig2.add_subplot(3, 1, 1)
  3165. ax22 = fig2.add_subplot(3, 1, 2)
  3166. ax23 = fig2.add_subplot(3, 1, 3)
  3167. ax11.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3168. pad_to=pad_to, sides='default', mode='magnitude')
  3169. ax12.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3170. pad_to=pad_to, sides='onesided', mode='magnitude')
  3171. ax13.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3172. pad_to=pad_to, sides='twosided', mode='magnitude')
  3173. ax21.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3174. pad_to=pad_to, sides='default', mode='magnitude',
  3175. scale='linear', norm=matplotlib.colors.LogNorm())
  3176. ax22.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3177. pad_to=pad_to, sides='onesided', mode='magnitude',
  3178. scale='linear', norm=matplotlib.colors.LogNorm())
  3179. ax23.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3180. pad_to=pad_to, sides='twosided', mode='magnitude',
  3181. scale='linear', norm=matplotlib.colors.LogNorm())
  3182. @image_comparison(['specgram_magnitude_noise.png',
  3183. 'specgram_magnitude_noise_linear.png'],
  3184. remove_text=True, style='default')
  3185. def test_specgram_magnitude_noise():
  3186. '''test axes.specgram in magnitude mode with noise stimuli'''
  3187. # use former defaults to match existing baseline image
  3188. matplotlib.rcParams['image.interpolation'] = 'nearest'
  3189. np.random.seed(0)
  3190. n = 1000
  3191. Fs = 10.
  3192. NFFT = int(10 * Fs / 11)
  3193. noverlap = int(NFFT / 2)
  3194. pad_to = int(2 ** np.ceil(np.log2(NFFT)))
  3195. y1 = np.random.standard_normal(n)
  3196. y2 = np.random.rand(n)
  3197. y = np.hstack([y1, y2])
  3198. fig1 = plt.figure()
  3199. fig2 = plt.figure()
  3200. ax11 = fig1.add_subplot(3, 1, 1)
  3201. ax12 = fig1.add_subplot(3, 1, 2)
  3202. ax13 = fig1.add_subplot(3, 1, 3)
  3203. ax21 = fig2.add_subplot(3, 1, 1)
  3204. ax22 = fig2.add_subplot(3, 1, 2)
  3205. ax23 = fig2.add_subplot(3, 1, 3)
  3206. ax11.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3207. pad_to=pad_to, sides='default', mode='magnitude')
  3208. ax12.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3209. pad_to=pad_to, sides='onesided', mode='magnitude')
  3210. ax13.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3211. pad_to=pad_to, sides='twosided', mode='magnitude')
  3212. ax21.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3213. pad_to=pad_to, sides='default', mode='magnitude',
  3214. scale='linear', norm=matplotlib.colors.LogNorm())
  3215. ax22.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3216. pad_to=pad_to, sides='onesided', mode='magnitude',
  3217. scale='linear', norm=matplotlib.colors.LogNorm())
  3218. ax23.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3219. pad_to=pad_to, sides='twosided', mode='magnitude',
  3220. scale='linear', norm=matplotlib.colors.LogNorm())
  3221. @image_comparison(['specgram_angle_freqs.png'],
  3222. remove_text=True, tol=0.007, style='default')
  3223. def test_specgram_angle_freqs():
  3224. '''test axes.specgram in angle mode with sinusoidal stimuli'''
  3225. # use former defaults to match existing baseline image
  3226. matplotlib.rcParams['image.interpolation'] = 'nearest'
  3227. n = 1000
  3228. Fs = 10.
  3229. fstims1 = [Fs/4, Fs/5, Fs/11]
  3230. fstims2 = [Fs/4.7, Fs/5.6, Fs/11.9]
  3231. NFFT = int(10 * Fs / min(fstims1 + fstims2))
  3232. noverlap = int(NFFT / 2)
  3233. pad_to = int(2 ** np.ceil(np.log2(NFFT)))
  3234. x = np.arange(0, n, 1/Fs)
  3235. y1 = np.zeros(x.size)
  3236. y2 = np.zeros(x.size)
  3237. for i, (fstim1, fstim2) in enumerate(zip(fstims1, fstims2)):
  3238. y1 += np.sin(fstim1 * x * np.pi * 2)
  3239. y2 += np.sin(fstim2 * x * np.pi * 2)
  3240. y1[-1] = y1[-1]/y1[-1]
  3241. y2[-1] = y2[-1]/y2[-1]
  3242. y = np.hstack([y1, y2])
  3243. fig1 = plt.figure()
  3244. ax11 = fig1.add_subplot(3, 1, 1)
  3245. ax12 = fig1.add_subplot(3, 1, 2)
  3246. ax13 = fig1.add_subplot(3, 1, 3)
  3247. ax11.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3248. pad_to=pad_to, sides='default', mode='angle')
  3249. ax12.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3250. pad_to=pad_to, sides='onesided', mode='angle')
  3251. ax13.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3252. pad_to=pad_to, sides='twosided', mode='angle')
  3253. with pytest.raises(ValueError):
  3254. ax11.specgram(y, NFFT=NFFT, Fs=Fs,
  3255. noverlap=noverlap, pad_to=pad_to, sides='default',
  3256. mode='phase', scale='dB')
  3257. with pytest.raises(ValueError):
  3258. ax12.specgram(y, NFFT=NFFT, Fs=Fs,
  3259. noverlap=noverlap, pad_to=pad_to, sides='onesided',
  3260. mode='phase', scale='dB')
  3261. with pytest.raises(ValueError):
  3262. ax13.specgram(y, NFFT=NFFT, Fs=Fs,
  3263. noverlap=noverlap, pad_to=pad_to, sides='twosided',
  3264. mode='phase', scale='dB')
  3265. @image_comparison(['specgram_angle_noise.png'],
  3266. remove_text=True, style='default')
  3267. def test_specgram_noise_angle():
  3268. '''test axes.specgram in angle mode with noise stimuli'''
  3269. # use former defaults to match existing baseline image
  3270. matplotlib.rcParams['image.interpolation'] = 'nearest'
  3271. np.random.seed(0)
  3272. n = 1000
  3273. Fs = 10.
  3274. NFFT = int(10 * Fs / 11)
  3275. noverlap = int(NFFT / 2)
  3276. pad_to = int(2 ** np.ceil(np.log2(NFFT)))
  3277. y1 = np.random.standard_normal(n)
  3278. y2 = np.random.rand(n)
  3279. y = np.hstack([y1, y2])
  3280. fig1 = plt.figure()
  3281. ax11 = fig1.add_subplot(3, 1, 1)
  3282. ax12 = fig1.add_subplot(3, 1, 2)
  3283. ax13 = fig1.add_subplot(3, 1, 3)
  3284. ax11.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3285. pad_to=pad_to, sides='default', mode='angle')
  3286. ax12.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3287. pad_to=pad_to, sides='onesided', mode='angle')
  3288. ax13.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3289. pad_to=pad_to, sides='twosided', mode='angle')
  3290. with pytest.raises(ValueError):
  3291. ax11.specgram(y, NFFT=NFFT, Fs=Fs,
  3292. noverlap=noverlap, pad_to=pad_to, sides='default',
  3293. mode='phase', scale='dB')
  3294. with pytest.raises(ValueError):
  3295. ax12.specgram(y, NFFT=NFFT, Fs=Fs,
  3296. noverlap=noverlap, pad_to=pad_to, sides='onesided',
  3297. mode='phase', scale='dB')
  3298. with pytest.raises(ValueError):
  3299. ax13.specgram(y, NFFT=NFFT, Fs=Fs,
  3300. noverlap=noverlap, pad_to=pad_to, sides='twosided',
  3301. mode='phase', scale='dB')
  3302. @image_comparison(['specgram_phase_freqs.png'],
  3303. remove_text=True, style='default')
  3304. def test_specgram_freqs_phase():
  3305. '''test axes.specgram in phase mode with sinusoidal stimuli'''
  3306. # use former defaults to match existing baseline image
  3307. matplotlib.rcParams['image.interpolation'] = 'nearest'
  3308. n = 1000
  3309. Fs = 10.
  3310. fstims1 = [Fs/4, Fs/5, Fs/11]
  3311. fstims2 = [Fs/4.7, Fs/5.6, Fs/11.9]
  3312. NFFT = int(10 * Fs / min(fstims1 + fstims2))
  3313. noverlap = int(NFFT / 2)
  3314. pad_to = int(2 ** np.ceil(np.log2(NFFT)))
  3315. x = np.arange(0, n, 1/Fs)
  3316. y1 = np.zeros(x.size)
  3317. y2 = np.zeros(x.size)
  3318. for i, (fstim1, fstim2) in enumerate(zip(fstims1, fstims2)):
  3319. y1 += np.sin(fstim1 * x * np.pi * 2)
  3320. y2 += np.sin(fstim2 * x * np.pi * 2)
  3321. y1[-1] = y1[-1]/y1[-1]
  3322. y2[-1] = y2[-1]/y2[-1]
  3323. y = np.hstack([y1, y2])
  3324. fig1 = plt.figure()
  3325. ax11 = fig1.add_subplot(3, 1, 1)
  3326. ax12 = fig1.add_subplot(3, 1, 2)
  3327. ax13 = fig1.add_subplot(3, 1, 3)
  3328. ax11.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3329. pad_to=pad_to, sides='default', mode='phase')
  3330. ax12.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3331. pad_to=pad_to, sides='onesided', mode='phase')
  3332. ax13.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3333. pad_to=pad_to, sides='twosided', mode='phase')
  3334. with pytest.raises(ValueError):
  3335. ax11.specgram(y, NFFT=NFFT, Fs=Fs,
  3336. noverlap=noverlap, pad_to=pad_to, sides='default',
  3337. mode='phase', scale='dB')
  3338. with pytest.raises(ValueError):
  3339. ax12.specgram(y, NFFT=NFFT, Fs=Fs,
  3340. noverlap=noverlap, pad_to=pad_to, sides='onesided',
  3341. mode='phase', scale='dB')
  3342. with pytest.raises(ValueError):
  3343. ax13.specgram(y, NFFT=NFFT, Fs=Fs,
  3344. noverlap=noverlap, pad_to=pad_to, sides='twosided',
  3345. mode='phase', scale='dB')
  3346. @image_comparison(['specgram_phase_noise.png'],
  3347. remove_text=True, style='default')
  3348. def test_specgram_noise_phase():
  3349. '''test axes.specgram in phase mode with noise stimuli'''
  3350. # use former defaults to match existing baseline image
  3351. matplotlib.rcParams['image.interpolation'] = 'nearest'
  3352. np.random.seed(0)
  3353. n = 1000
  3354. Fs = 10.
  3355. NFFT = int(10 * Fs / 11)
  3356. noverlap = int(NFFT / 2)
  3357. pad_to = int(2 ** np.ceil(np.log2(NFFT)))
  3358. y1 = np.random.standard_normal(n)
  3359. y2 = np.random.rand(n)
  3360. y = np.hstack([y1, y2])
  3361. fig1 = plt.figure()
  3362. ax11 = fig1.add_subplot(3, 1, 1)
  3363. ax12 = fig1.add_subplot(3, 1, 2)
  3364. ax13 = fig1.add_subplot(3, 1, 3)
  3365. ax11.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3366. pad_to=pad_to, sides='default', mode='phase')
  3367. ax12.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3368. pad_to=pad_to, sides='onesided', mode='phase')
  3369. ax13.specgram(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3370. pad_to=pad_to, sides='twosided', mode='phase')
  3371. with pytest.raises(ValueError):
  3372. ax11.specgram(y, NFFT=NFFT, Fs=Fs,
  3373. noverlap=noverlap, pad_to=pad_to, sides='default',
  3374. mode='phase', scale='dB')
  3375. with pytest.raises(ValueError):
  3376. ax12.specgram(y, NFFT=NFFT, Fs=Fs,
  3377. noverlap=noverlap, pad_to=pad_to, sides='onesided',
  3378. mode='phase', scale='dB')
  3379. with pytest.raises(ValueError):
  3380. ax13.specgram(y, NFFT=NFFT, Fs=Fs,
  3381. noverlap=noverlap, pad_to=pad_to, sides='twosided',
  3382. mode='phase', scale='dB')
  3383. @image_comparison(['psd_freqs.png'], remove_text=True)
  3384. def test_psd_freqs():
  3385. '''test axes.psd with sinusoidal stimuli'''
  3386. n = 10000
  3387. Fs = 100.
  3388. fstims1 = [Fs/4, Fs/5, Fs/11]
  3389. fstims2 = [Fs/4.7, Fs/5.6, Fs/11.9]
  3390. NFFT = int(1000 * Fs / min(fstims1 + fstims2))
  3391. noverlap = int(NFFT / 2)
  3392. pad_to = int(2 ** np.ceil(np.log2(NFFT)))
  3393. x = np.arange(0, n, 1/Fs)
  3394. y1 = np.zeros(x.size)
  3395. y2 = np.zeros(x.size)
  3396. for fstim1, fstim2 in zip(fstims1, fstims2):
  3397. y1 += np.sin(fstim1 * x * np.pi * 2)
  3398. y2 += np.sin(fstim2 * x * np.pi * 2)
  3399. y = np.hstack([y1, y2])
  3400. fig = plt.figure()
  3401. ax1 = fig.add_subplot(3, 1, 1)
  3402. ax2 = fig.add_subplot(3, 1, 2)
  3403. ax3 = fig.add_subplot(3, 1, 3)
  3404. psd1, freqs1 = ax1.psd(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3405. pad_to=pad_to, sides='default')
  3406. psd2, freqs2 = ax2.psd(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3407. pad_to=pad_to, sides='onesided',
  3408. return_line=False)
  3409. psd3, freqs3, line3 = ax3.psd(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3410. pad_to=pad_to, sides='twosided',
  3411. return_line=True)
  3412. ax1.set_xlabel('')
  3413. ax2.set_xlabel('')
  3414. ax3.set_xlabel('')
  3415. ax1.set_ylabel('')
  3416. ax2.set_ylabel('')
  3417. ax3.set_ylabel('')
  3418. @image_comparison(['psd_noise.png'], remove_text=True)
  3419. def test_psd_noise():
  3420. '''test axes.psd with noise stimuli'''
  3421. np.random.seed(0)
  3422. n = 10000
  3423. Fs = 100.
  3424. NFFT = int(1000 * Fs / 11)
  3425. noverlap = int(NFFT / 2)
  3426. pad_to = int(2 ** np.ceil(np.log2(NFFT)))
  3427. y1 = np.random.standard_normal(n)
  3428. y2 = np.random.rand(n)
  3429. y = np.hstack([y1, y2])
  3430. fig = plt.figure()
  3431. ax1 = fig.add_subplot(3, 1, 1)
  3432. ax2 = fig.add_subplot(3, 1, 2)
  3433. ax3 = fig.add_subplot(3, 1, 3)
  3434. psd1, freqs1 = ax1.psd(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3435. pad_to=pad_to, sides='default')
  3436. psd2, freqs2 = ax2.psd(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3437. pad_to=pad_to, sides='onesided',
  3438. return_line=False)
  3439. psd3, freqs3, line3 = ax3.psd(y, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3440. pad_to=pad_to, sides='twosided',
  3441. return_line=True)
  3442. ax1.set_xlabel('')
  3443. ax2.set_xlabel('')
  3444. ax3.set_xlabel('')
  3445. ax1.set_ylabel('')
  3446. ax2.set_ylabel('')
  3447. ax3.set_ylabel('')
  3448. @image_comparison(['csd_freqs.png'], remove_text=True, tol=0.002)
  3449. def test_csd_freqs():
  3450. '''test axes.csd with sinusoidal stimuli'''
  3451. n = 10000
  3452. Fs = 100.
  3453. fstims1 = [Fs/4, Fs/5, Fs/11]
  3454. fstims2 = [Fs/4.7, Fs/5.6, Fs/11.9]
  3455. NFFT = int(1000 * Fs / min(fstims1 + fstims2))
  3456. noverlap = int(NFFT / 2)
  3457. pad_to = int(2 ** np.ceil(np.log2(NFFT)))
  3458. x = np.arange(0, n, 1/Fs)
  3459. y1 = np.zeros(x.size)
  3460. y2 = np.zeros(x.size)
  3461. for fstim1, fstim2 in zip(fstims1, fstims2):
  3462. y1 += np.sin(fstim1 * x * np.pi * 2)
  3463. y2 += np.sin(fstim2 * x * np.pi * 2)
  3464. fig = plt.figure()
  3465. ax1 = fig.add_subplot(3, 1, 1)
  3466. ax2 = fig.add_subplot(3, 1, 2)
  3467. ax3 = fig.add_subplot(3, 1, 3)
  3468. csd1, freqs1 = ax1.csd(y1, y2, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3469. pad_to=pad_to, sides='default')
  3470. csd2, freqs2 = ax2.csd(y1, y2, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3471. pad_to=pad_to, sides='onesided',
  3472. return_line=False)
  3473. csd3, freqs3, line3 = ax3.csd(y1, y2, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3474. pad_to=pad_to, sides='twosided',
  3475. return_line=True)
  3476. ax1.set_xlabel('')
  3477. ax2.set_xlabel('')
  3478. ax3.set_xlabel('')
  3479. ax1.set_ylabel('')
  3480. ax2.set_ylabel('')
  3481. ax3.set_ylabel('')
  3482. @image_comparison(['csd_noise.png'], remove_text=True)
  3483. def test_csd_noise():
  3484. '''test axes.csd with noise stimuli'''
  3485. np.random.seed(0)
  3486. n = 10000
  3487. Fs = 100.
  3488. NFFT = int(1000 * Fs / 11)
  3489. noverlap = int(NFFT / 2)
  3490. pad_to = int(2 ** np.ceil(np.log2(NFFT)))
  3491. y1 = np.random.standard_normal(n)
  3492. y2 = np.random.rand(n)
  3493. fig = plt.figure()
  3494. ax1 = fig.add_subplot(3, 1, 1)
  3495. ax2 = fig.add_subplot(3, 1, 2)
  3496. ax3 = fig.add_subplot(3, 1, 3)
  3497. csd1, freqs1 = ax1.csd(y1, y2, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3498. pad_to=pad_to, sides='default')
  3499. csd2, freqs2 = ax2.csd(y1, y2, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3500. pad_to=pad_to, sides='onesided',
  3501. return_line=False)
  3502. csd3, freqs3, line3 = ax3.csd(y1, y2, NFFT=NFFT, Fs=Fs, noverlap=noverlap,
  3503. pad_to=pad_to, sides='twosided',
  3504. return_line=True)
  3505. ax1.set_xlabel('')
  3506. ax2.set_xlabel('')
  3507. ax3.set_xlabel('')
  3508. ax1.set_ylabel('')
  3509. ax2.set_ylabel('')
  3510. ax3.set_ylabel('')
  3511. @image_comparison(['magnitude_spectrum_freqs_linear.png',
  3512. 'magnitude_spectrum_freqs_dB.png'],
  3513. remove_text=True)
  3514. def test_magnitude_spectrum_freqs():
  3515. '''test axes.magnitude_spectrum with sinusoidal stimuli'''
  3516. n = 10000
  3517. Fs = 100.
  3518. fstims1 = [Fs/4, Fs/5, Fs/11]
  3519. NFFT = int(1000 * Fs / min(fstims1))
  3520. pad_to = int(2 ** np.ceil(np.log2(NFFT)))
  3521. x = np.arange(0, n, 1/Fs)
  3522. y = np.zeros(x.size)
  3523. for i, fstim1 in enumerate(fstims1):
  3524. y += np.sin(fstim1 * x * np.pi * 2) * 10**i
  3525. y = y
  3526. fig1 = plt.figure()
  3527. fig2 = plt.figure()
  3528. ax11 = fig1.add_subplot(3, 1, 1)
  3529. ax12 = fig1.add_subplot(3, 1, 2)
  3530. ax13 = fig1.add_subplot(3, 1, 3)
  3531. ax21 = fig2.add_subplot(3, 1, 1)
  3532. ax22 = fig2.add_subplot(3, 1, 2)
  3533. ax23 = fig2.add_subplot(3, 1, 3)
  3534. spec11, freqs11, line11 = ax11.magnitude_spectrum(y, Fs=Fs, pad_to=pad_to,
  3535. sides='default')
  3536. spec12, freqs12, line12 = ax12.magnitude_spectrum(y, Fs=Fs, pad_to=pad_to,
  3537. sides='onesided')
  3538. spec13, freqs13, line13 = ax13.magnitude_spectrum(y, Fs=Fs, pad_to=pad_to,
  3539. sides='twosided')
  3540. spec21, freqs21, line21 = ax21.magnitude_spectrum(y, Fs=Fs, pad_to=pad_to,
  3541. sides='default',
  3542. scale='dB')
  3543. spec22, freqs22, line22 = ax22.magnitude_spectrum(y, Fs=Fs, pad_to=pad_to,
  3544. sides='onesided',
  3545. scale='dB')
  3546. spec23, freqs23, line23 = ax23.magnitude_spectrum(y, Fs=Fs, pad_to=pad_to,
  3547. sides='twosided',
  3548. scale='dB')
  3549. ax11.set_xlabel('')
  3550. ax12.set_xlabel('')
  3551. ax13.set_xlabel('')
  3552. ax11.set_ylabel('')
  3553. ax12.set_ylabel('')
  3554. ax13.set_ylabel('')
  3555. ax21.set_xlabel('')
  3556. ax22.set_xlabel('')
  3557. ax23.set_xlabel('')
  3558. ax21.set_ylabel('')
  3559. ax22.set_ylabel('')
  3560. ax23.set_ylabel('')
  3561. @image_comparison(['magnitude_spectrum_noise_linear.png',
  3562. 'magnitude_spectrum_noise_dB.png'],
  3563. remove_text=True)
  3564. def test_magnitude_spectrum_noise():
  3565. '''test axes.magnitude_spectrum with noise stimuli'''
  3566. np.random.seed(0)
  3567. n = 10000
  3568. Fs = 100.
  3569. NFFT = int(1000 * Fs / 11)
  3570. pad_to = int(2 ** np.ceil(np.log2(NFFT)))
  3571. y1 = np.random.standard_normal(n)
  3572. y2 = np.random.rand(n)
  3573. y = np.hstack([y1, y2]) - .5
  3574. fig1 = plt.figure()
  3575. fig2 = plt.figure()
  3576. ax11 = fig1.add_subplot(3, 1, 1)
  3577. ax12 = fig1.add_subplot(3, 1, 2)
  3578. ax13 = fig1.add_subplot(3, 1, 3)
  3579. ax21 = fig2.add_subplot(3, 1, 1)
  3580. ax22 = fig2.add_subplot(3, 1, 2)
  3581. ax23 = fig2.add_subplot(3, 1, 3)
  3582. spec11, freqs11, line11 = ax11.magnitude_spectrum(y, Fs=Fs, pad_to=pad_to,
  3583. sides='default')
  3584. spec12, freqs12, line12 = ax12.magnitude_spectrum(y, Fs=Fs, pad_to=pad_to,
  3585. sides='onesided')
  3586. spec13, freqs13, line13 = ax13.magnitude_spectrum(y, Fs=Fs, pad_to=pad_to,
  3587. sides='twosided')
  3588. spec21, freqs21, line21 = ax21.magnitude_spectrum(y, Fs=Fs, pad_to=pad_to,
  3589. sides='default',
  3590. scale='dB')
  3591. spec22, freqs22, line22 = ax22.magnitude_spectrum(y, Fs=Fs, pad_to=pad_to,
  3592. sides='onesided',
  3593. scale='dB')
  3594. spec23, freqs23, line23 = ax23.magnitude_spectrum(y, Fs=Fs, pad_to=pad_to,
  3595. sides='twosided',
  3596. scale='dB')
  3597. ax11.set_xlabel('')
  3598. ax12.set_xlabel('')
  3599. ax13.set_xlabel('')
  3600. ax11.set_ylabel('')
  3601. ax12.set_ylabel('')
  3602. ax13.set_ylabel('')
  3603. ax21.set_xlabel('')
  3604. ax22.set_xlabel('')
  3605. ax23.set_xlabel('')
  3606. ax21.set_ylabel('')
  3607. ax22.set_ylabel('')
  3608. ax23.set_ylabel('')
  3609. @image_comparison(['angle_spectrum_freqs.png'], remove_text=True)
  3610. def test_angle_spectrum_freqs():
  3611. '''test axes.angle_spectrum with sinusoidal stimuli'''
  3612. n = 10000
  3613. Fs = 100.
  3614. fstims1 = [Fs/4, Fs/5, Fs/11]
  3615. NFFT = int(1000 * Fs / min(fstims1))
  3616. pad_to = int(2 ** np.ceil(np.log2(NFFT)))
  3617. x = np.arange(0, n, 1/Fs)
  3618. y = np.zeros(x.size)
  3619. for i, fstim1 in enumerate(fstims1):
  3620. y += np.sin(fstim1 * x * np.pi * 2) * 10**i
  3621. y = y
  3622. fig = plt.figure()
  3623. ax1 = fig.add_subplot(3, 1, 1)
  3624. ax2 = fig.add_subplot(3, 1, 2)
  3625. ax3 = fig.add_subplot(3, 1, 3)
  3626. spec1, freqs1, line1 = ax1.angle_spectrum(y, Fs=Fs, pad_to=pad_to,
  3627. sides='default')
  3628. spec2, freqs2, line2 = ax2.angle_spectrum(y, Fs=Fs, pad_to=pad_to,
  3629. sides='onesided')
  3630. spec3, freqs3, line3 = ax3.angle_spectrum(y, Fs=Fs, pad_to=pad_to,
  3631. sides='twosided')
  3632. ax1.set_xlabel('')
  3633. ax2.set_xlabel('')
  3634. ax3.set_xlabel('')
  3635. ax1.set_ylabel('')
  3636. ax2.set_ylabel('')
  3637. ax3.set_ylabel('')
  3638. @image_comparison(['angle_spectrum_noise.png'], remove_text=True)
  3639. def test_angle_spectrum_noise():
  3640. '''test axes.angle_spectrum with noise stimuli'''
  3641. np.random.seed(0)
  3642. n = 10000
  3643. Fs = 100.
  3644. NFFT = int(1000 * Fs / 11)
  3645. pad_to = int(2 ** np.ceil(np.log2(NFFT)))
  3646. y1 = np.random.standard_normal(n)
  3647. y2 = np.random.rand(n)
  3648. y = np.hstack([y1, y2]) - .5
  3649. fig = plt.figure()
  3650. ax1 = fig.add_subplot(3, 1, 1)
  3651. ax2 = fig.add_subplot(3, 1, 2)
  3652. ax3 = fig.add_subplot(3, 1, 3)
  3653. spec1, freqs1, line1 = ax1.angle_spectrum(y, Fs=Fs, pad_to=pad_to,
  3654. sides='default')
  3655. spec2, freqs2, line2 = ax2.angle_spectrum(y, Fs=Fs, pad_to=pad_to,
  3656. sides='onesided')
  3657. spec3, freqs3, line3 = ax3.angle_spectrum(y, Fs=Fs, pad_to=pad_to,
  3658. sides='twosided')
  3659. ax1.set_xlabel('')
  3660. ax2.set_xlabel('')
  3661. ax3.set_xlabel('')
  3662. ax1.set_ylabel('')
  3663. ax2.set_ylabel('')
  3664. ax3.set_ylabel('')
  3665. @image_comparison(['phase_spectrum_freqs.png'], remove_text=True)
  3666. def test_phase_spectrum_freqs():
  3667. '''test axes.phase_spectrum with sinusoidal stimuli'''
  3668. n = 10000
  3669. Fs = 100.
  3670. fstims1 = [Fs/4, Fs/5, Fs/11]
  3671. NFFT = int(1000 * Fs / min(fstims1))
  3672. pad_to = int(2 ** np.ceil(np.log2(NFFT)))
  3673. x = np.arange(0, n, 1/Fs)
  3674. y = np.zeros(x.size)
  3675. for i, fstim1 in enumerate(fstims1):
  3676. y += np.sin(fstim1 * x * np.pi * 2) * 10**i
  3677. y = y
  3678. fig = plt.figure()
  3679. ax1 = fig.add_subplot(3, 1, 1)
  3680. ax2 = fig.add_subplot(3, 1, 2)
  3681. ax3 = fig.add_subplot(3, 1, 3)
  3682. spec1, freqs1, line1 = ax1.phase_spectrum(y, Fs=Fs, pad_to=pad_to,
  3683. sides='default')
  3684. spec2, freqs2, line2 = ax2.phase_spectrum(y, Fs=Fs, pad_to=pad_to,
  3685. sides='onesided')
  3686. spec3, freqs3, line3 = ax3.phase_spectrum(y, Fs=Fs, pad_to=pad_to,
  3687. sides='twosided')
  3688. ax1.set_xlabel('')
  3689. ax2.set_xlabel('')
  3690. ax3.set_xlabel('')
  3691. ax1.set_ylabel('')
  3692. ax2.set_ylabel('')
  3693. ax3.set_ylabel('')
  3694. @image_comparison(['phase_spectrum_noise.png'], remove_text=True)
  3695. def test_phase_spectrum_noise():
  3696. '''test axes.phase_spectrum with noise stimuli'''
  3697. np.random.seed(0)
  3698. n = 10000
  3699. Fs = 100.
  3700. NFFT = int(1000 * Fs / 11)
  3701. pad_to = int(2 ** np.ceil(np.log2(NFFT)))
  3702. y1 = np.random.standard_normal(n)
  3703. y2 = np.random.rand(n)
  3704. y = np.hstack([y1, y2]) - .5
  3705. fig = plt.figure()
  3706. ax1 = fig.add_subplot(3, 1, 1)
  3707. ax2 = fig.add_subplot(3, 1, 2)
  3708. ax3 = fig.add_subplot(3, 1, 3)
  3709. spec1, freqs1, line1 = ax1.phase_spectrum(y, Fs=Fs, pad_to=pad_to,
  3710. sides='default')
  3711. spec2, freqs2, line2 = ax2.phase_spectrum(y, Fs=Fs, pad_to=pad_to,
  3712. sides='onesided')
  3713. spec3, freqs3, line3 = ax3.phase_spectrum(y, Fs=Fs, pad_to=pad_to,
  3714. sides='twosided')
  3715. ax1.set_xlabel('')
  3716. ax2.set_xlabel('')
  3717. ax3.set_xlabel('')
  3718. ax1.set_ylabel('')
  3719. ax2.set_ylabel('')
  3720. ax3.set_ylabel('')
  3721. @image_comparison(['twin_spines.png'], remove_text=True)
  3722. def test_twin_spines():
  3723. def make_patch_spines_invisible(ax):
  3724. ax.set_frame_on(True)
  3725. ax.patch.set_visible(False)
  3726. for sp in ax.spines.values():
  3727. sp.set_visible(False)
  3728. fig = plt.figure(figsize=(4, 3))
  3729. fig.subplots_adjust(right=0.75)
  3730. host = fig.add_subplot(111)
  3731. par1 = host.twinx()
  3732. par2 = host.twinx()
  3733. # Offset the right spine of par2. The ticks and label have already been
  3734. # placed on the right by twinx above.
  3735. par2.spines["right"].set_position(("axes", 1.2))
  3736. # Having been created by twinx, par2 has its frame off, so the line of
  3737. # its detached spine is invisible. First, activate the frame but make
  3738. # the patch and spines invisible.
  3739. make_patch_spines_invisible(par2)
  3740. # Second, show the right spine.
  3741. par2.spines["right"].set_visible(True)
  3742. p1, = host.plot([0, 1, 2], [0, 1, 2], "b-")
  3743. p2, = par1.plot([0, 1, 2], [0, 3, 2], "r-")
  3744. p3, = par2.plot([0, 1, 2], [50, 30, 15], "g-")
  3745. host.set_xlim(0, 2)
  3746. host.set_ylim(0, 2)
  3747. par1.set_ylim(0, 4)
  3748. par2.set_ylim(1, 65)
  3749. host.yaxis.label.set_color(p1.get_color())
  3750. par1.yaxis.label.set_color(p2.get_color())
  3751. par2.yaxis.label.set_color(p3.get_color())
  3752. tkw = dict(size=4, width=1.5)
  3753. host.tick_params(axis='y', colors=p1.get_color(), **tkw)
  3754. par1.tick_params(axis='y', colors=p2.get_color(), **tkw)
  3755. par2.tick_params(axis='y', colors=p3.get_color(), **tkw)
  3756. host.tick_params(axis='x', **tkw)
  3757. @image_comparison(['twin_spines_on_top.png', 'twin_spines_on_top.png'],
  3758. remove_text=True)
  3759. def test_twin_spines_on_top():
  3760. matplotlib.rcParams['axes.linewidth'] = 48.0
  3761. matplotlib.rcParams['lines.linewidth'] = 48.0
  3762. fig = plt.figure()
  3763. ax1 = fig.add_subplot(1, 1, 1)
  3764. data = np.array([[1000, 1100, 1200, 1250],
  3765. [310, 301, 360, 400]])
  3766. ax2 = ax1.twinx()
  3767. ax1.plot(data[0], data[1]/1E3, color='#BEAED4')
  3768. ax1.fill_between(data[0], data[1]/1E3, color='#BEAED4', alpha=.8)
  3769. ax2.plot(data[0], data[1]/1E3, color='#7FC97F')
  3770. ax2.fill_between(data[0], data[1]/1E3, color='#7FC97F', alpha=.5)
  3771. # Reuse testcase from above for a labeled data test
  3772. data = {"i": data[0], "j": data[1]/1E3}
  3773. fig = plt.figure()
  3774. ax1 = fig.add_subplot(1, 1, 1)
  3775. ax2 = ax1.twinx()
  3776. ax1.plot("i", "j", color='#BEAED4', data=data)
  3777. ax1.fill_between("i", "j", color='#BEAED4', alpha=.8, data=data)
  3778. ax2.plot("i", "j", color='#7FC97F', data=data)
  3779. ax2.fill_between("i", "j", color='#7FC97F', alpha=.5, data=data)
  3780. def test_rcparam_grid_minor():
  3781. orig_grid = matplotlib.rcParams['axes.grid']
  3782. orig_locator = matplotlib.rcParams['axes.grid.which']
  3783. matplotlib.rcParams['axes.grid'] = True
  3784. values = (
  3785. (('both'), (True, True)),
  3786. (('major'), (True, False)),
  3787. (('minor'), (False, True))
  3788. )
  3789. for locator, result in values:
  3790. matplotlib.rcParams['axes.grid.which'] = locator
  3791. fig = plt.figure()
  3792. ax = fig.add_subplot(1, 1, 1)
  3793. assert (ax.xaxis._gridOnMajor, ax.xaxis._gridOnMinor) == result
  3794. matplotlib.rcParams['axes.grid'] = orig_grid
  3795. matplotlib.rcParams['axes.grid.which'] = orig_locator
  3796. def test_vline_limit():
  3797. fig = plt.figure()
  3798. ax = fig.gca()
  3799. ax.axvline(0.5)
  3800. ax.plot([-0.1, 0, 0.2, 0.1])
  3801. (ymin, ymax) = ax.get_ylim()
  3802. assert_allclose(ax.get_ylim(), (-.1, .2))
  3803. def test_empty_shared_subplots():
  3804. # empty plots with shared axes inherit limits from populated plots
  3805. fig, axs = plt.subplots(nrows=1, ncols=2, sharex=True, sharey=True)
  3806. axs[0].plot([1, 2, 3], [2, 4, 6])
  3807. x0, x1 = axs[1].get_xlim()
  3808. y0, y1 = axs[1].get_ylim()
  3809. assert x0 <= 1
  3810. assert x1 >= 3
  3811. assert y0 <= 2
  3812. assert y1 >= 6
  3813. def test_shared_with_aspect_1():
  3814. # allow sharing one axis
  3815. for adjustable in ['box', 'datalim']:
  3816. fig, axs = plt.subplots(nrows=2, sharex=True)
  3817. axs[0].set_aspect(2, adjustable=adjustable, share=True)
  3818. assert axs[1].get_aspect() == 2
  3819. assert axs[1].get_adjustable() == adjustable
  3820. fig, axs = plt.subplots(nrows=2, sharex=True)
  3821. axs[0].set_aspect(2, adjustable=adjustable)
  3822. assert axs[1].get_aspect() == 'auto'
  3823. def test_shared_with_aspect_2():
  3824. # Share 2 axes only with 'box':
  3825. fig, axs = plt.subplots(nrows=2, sharex=True, sharey=True)
  3826. axs[0].set_aspect(2, share=True)
  3827. axs[0].plot([1, 2], [3, 4])
  3828. axs[1].plot([3, 4], [1, 2])
  3829. plt.draw() # Trigger apply_aspect().
  3830. assert axs[0].get_xlim() == axs[1].get_xlim()
  3831. assert axs[0].get_ylim() == axs[1].get_ylim()
  3832. def test_shared_with_aspect_3():
  3833. # Different aspect ratios:
  3834. for adjustable in ['box', 'datalim']:
  3835. fig, axs = plt.subplots(nrows=2, sharey=True)
  3836. axs[0].set_aspect(2, adjustable=adjustable)
  3837. axs[1].set_aspect(0.5, adjustable=adjustable)
  3838. axs[0].plot([1, 2], [3, 4])
  3839. axs[1].plot([3, 4], [1, 2])
  3840. plt.draw() # Trigger apply_aspect().
  3841. assert axs[0].get_xlim() != axs[1].get_xlim()
  3842. assert axs[0].get_ylim() == axs[1].get_ylim()
  3843. fig_aspect = fig.bbox_inches.height / fig.bbox_inches.width
  3844. for ax in axs:
  3845. p = ax.get_position()
  3846. box_aspect = p.height / p.width
  3847. lim_aspect = ax.viewLim.height / ax.viewLim.width
  3848. expected = fig_aspect * box_aspect / lim_aspect
  3849. assert round(expected, 4) == round(ax.get_aspect(), 4)
  3850. def test_polar_not_datalim_adjustable():
  3851. ax = plt.figure().add_subplot(projection="polar")
  3852. with pytest.raises(ValueError):
  3853. ax.set_adjustable("datalim")
  3854. @pytest.mark.parametrize('twin', ('x', 'y'))
  3855. def test_twin_with_aspect(twin):
  3856. fig, ax = plt.subplots()
  3857. # test twinx or twiny
  3858. ax_twin = getattr(ax, 'twin{}'.format(twin))()
  3859. ax.set_aspect(5)
  3860. ax_twin.set_aspect(2)
  3861. assert_array_equal(ax.bbox.extents,
  3862. ax_twin.bbox.extents)
  3863. def test_relim_visible_only():
  3864. x1 = (0., 10.)
  3865. y1 = (0., 10.)
  3866. x2 = (-10., 20.)
  3867. y2 = (-10., 30.)
  3868. fig = matplotlib.figure.Figure()
  3869. ax = fig.add_subplot(111)
  3870. ax.plot(x1, y1)
  3871. assert ax.get_xlim() == x1
  3872. assert ax.get_ylim() == y1
  3873. l = ax.plot(x2, y2)
  3874. assert ax.get_xlim() == x2
  3875. assert ax.get_ylim() == y2
  3876. l[0].set_visible(False)
  3877. assert ax.get_xlim() == x2
  3878. assert ax.get_ylim() == y2
  3879. ax.relim(visible_only=True)
  3880. ax.autoscale_view()
  3881. assert ax.get_xlim() == x1
  3882. assert ax.get_ylim() == y1
  3883. def test_text_labelsize():
  3884. """
  3885. tests for issue #1172
  3886. """
  3887. fig = plt.figure()
  3888. ax = fig.gca()
  3889. ax.tick_params(labelsize='large')
  3890. ax.tick_params(direction='out')
  3891. @image_comparison(['pie_default.png'])
  3892. def test_pie_default():
  3893. # The slices will be ordered and plotted counter-clockwise.
  3894. labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
  3895. sizes = [15, 30, 45, 10]
  3896. colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral']
  3897. explode = (0, 0.1, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs')
  3898. fig1, ax1 = plt.subplots(figsize=(8, 6))
  3899. ax1.pie(sizes, explode=explode, labels=labels, colors=colors,
  3900. autopct='%1.1f%%', shadow=True, startangle=90)
  3901. @image_comparison(['pie_linewidth_0', 'pie_linewidth_0', 'pie_linewidth_0'],
  3902. extensions=['png'])
  3903. def test_pie_linewidth_0():
  3904. # The slices will be ordered and plotted counter-clockwise.
  3905. labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
  3906. sizes = [15, 30, 45, 10]
  3907. colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral']
  3908. explode = (0, 0.1, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs')
  3909. plt.pie(sizes, explode=explode, labels=labels, colors=colors,
  3910. autopct='%1.1f%%', shadow=True, startangle=90,
  3911. wedgeprops={'linewidth': 0})
  3912. # Set aspect ratio to be equal so that pie is drawn as a circle.
  3913. plt.axis('equal')
  3914. # Reuse testcase from above for a labeled data test
  3915. data = {"l": labels, "s": sizes, "c": colors, "ex": explode}
  3916. fig = plt.figure()
  3917. ax = fig.gca()
  3918. ax.pie("s", explode="ex", labels="l", colors="c",
  3919. autopct='%1.1f%%', shadow=True, startangle=90,
  3920. wedgeprops={'linewidth': 0}, data=data)
  3921. ax.axis('equal')
  3922. # And again to test the pyplot functions which should also be able to be
  3923. # called with a data kwarg
  3924. plt.figure()
  3925. plt.pie("s", explode="ex", labels="l", colors="c",
  3926. autopct='%1.1f%%', shadow=True, startangle=90,
  3927. wedgeprops={'linewidth': 0}, data=data)
  3928. plt.axis('equal')
  3929. @image_comparison(['pie_center_radius.png'])
  3930. def test_pie_center_radius():
  3931. # The slices will be ordered and plotted counter-clockwise.
  3932. labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
  3933. sizes = [15, 30, 45, 10]
  3934. colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral']
  3935. explode = (0, 0.1, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs')
  3936. plt.pie(sizes, explode=explode, labels=labels, colors=colors,
  3937. autopct='%1.1f%%', shadow=True, startangle=90,
  3938. wedgeprops={'linewidth': 0}, center=(1, 2), radius=1.5)
  3939. plt.annotate("Center point", xy=(1, 2), xytext=(1, 1.5),
  3940. arrowprops=dict(arrowstyle="->",
  3941. connectionstyle="arc3"))
  3942. # Set aspect ratio to be equal so that pie is drawn as a circle.
  3943. plt.axis('equal')
  3944. @image_comparison(['pie_linewidth_2.png'])
  3945. def test_pie_linewidth_2():
  3946. # The slices will be ordered and plotted counter-clockwise.
  3947. labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
  3948. sizes = [15, 30, 45, 10]
  3949. colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral']
  3950. explode = (0, 0.1, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs')
  3951. plt.pie(sizes, explode=explode, labels=labels, colors=colors,
  3952. autopct='%1.1f%%', shadow=True, startangle=90,
  3953. wedgeprops={'linewidth': 2})
  3954. # Set aspect ratio to be equal so that pie is drawn as a circle.
  3955. plt.axis('equal')
  3956. @image_comparison(['pie_ccw_true.png'])
  3957. def test_pie_ccw_true():
  3958. # The slices will be ordered and plotted counter-clockwise.
  3959. labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
  3960. sizes = [15, 30, 45, 10]
  3961. colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral']
  3962. explode = (0, 0.1, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs')
  3963. plt.pie(sizes, explode=explode, labels=labels, colors=colors,
  3964. autopct='%1.1f%%', shadow=True, startangle=90,
  3965. counterclock=True)
  3966. # Set aspect ratio to be equal so that pie is drawn as a circle.
  3967. plt.axis('equal')
  3968. @image_comparison(['pie_frame_grid.png'])
  3969. def test_pie_frame_grid():
  3970. # The slices will be ordered and plotted counter-clockwise.
  3971. labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
  3972. sizes = [15, 30, 45, 10]
  3973. colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral']
  3974. # only "explode" the 2nd slice (i.e. 'Hogs')
  3975. explode = (0, 0.1, 0, 0)
  3976. plt.pie(sizes, explode=explode, labels=labels, colors=colors,
  3977. autopct='%1.1f%%', shadow=True, startangle=90,
  3978. wedgeprops={'linewidth': 0},
  3979. frame=True, center=(2, 2))
  3980. plt.pie(sizes[::-1], explode=explode, labels=labels, colors=colors,
  3981. autopct='%1.1f%%', shadow=True, startangle=90,
  3982. wedgeprops={'linewidth': 0},
  3983. frame=True, center=(5, 2))
  3984. plt.pie(sizes, explode=explode[::-1], labels=labels, colors=colors,
  3985. autopct='%1.1f%%', shadow=True, startangle=90,
  3986. wedgeprops={'linewidth': 0},
  3987. frame=True, center=(3, 5))
  3988. # Set aspect ratio to be equal so that pie is drawn as a circle.
  3989. plt.axis('equal')
  3990. @image_comparison(['pie_rotatelabels_true.png'])
  3991. def test_pie_rotatelabels_true():
  3992. # The slices will be ordered and plotted counter-clockwise.
  3993. labels = 'Hogwarts', 'Frogs', 'Dogs', 'Logs'
  3994. sizes = [15, 30, 45, 10]
  3995. colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral']
  3996. explode = (0, 0.1, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs')
  3997. plt.pie(sizes, explode=explode, labels=labels, colors=colors,
  3998. autopct='%1.1f%%', shadow=True, startangle=90,
  3999. rotatelabels=True)
  4000. # Set aspect ratio to be equal so that pie is drawn as a circle.
  4001. plt.axis('equal')
  4002. @image_comparison(['pie_no_label.png'])
  4003. def test_pie_nolabel_but_legend():
  4004. labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
  4005. sizes = [15, 30, 45, 10]
  4006. colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral']
  4007. explode = (0, 0.1, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs')
  4008. plt.pie(sizes, explode=explode, labels=labels, colors=colors,
  4009. autopct='%1.1f%%', shadow=True, startangle=90, labeldistance=None,
  4010. rotatelabels=True)
  4011. plt.axis('equal')
  4012. plt.ylim(-1.2, 1.2)
  4013. plt.legend()
  4014. def test_pie_textprops():
  4015. data = [23, 34, 45]
  4016. labels = ["Long name 1", "Long name 2", "Long name 3"]
  4017. textprops = dict(horizontalalignment="center",
  4018. verticalalignment="top",
  4019. rotation=90,
  4020. rotation_mode="anchor",
  4021. size=12, color="red")
  4022. _, texts, autopct = plt.gca().pie(data, labels=labels, autopct='%.2f',
  4023. textprops=textprops)
  4024. for labels in [texts, autopct]:
  4025. for tx in labels:
  4026. assert tx.get_ha() == textprops["horizontalalignment"]
  4027. assert tx.get_va() == textprops["verticalalignment"]
  4028. assert tx.get_rotation() == textprops["rotation"]
  4029. assert tx.get_rotation_mode() == textprops["rotation_mode"]
  4030. assert tx.get_size() == textprops["size"]
  4031. assert tx.get_color() == textprops["color"]
  4032. @image_comparison(['set_get_ticklabels.png'])
  4033. def test_set_get_ticklabels():
  4034. # test issue 2246
  4035. fig, ax = plt.subplots(2)
  4036. ha = ['normal', 'set_x/yticklabels']
  4037. ax[0].plot(np.arange(10))
  4038. ax[0].set_title(ha[0])
  4039. ax[1].plot(np.arange(10))
  4040. ax[1].set_title(ha[1])
  4041. # set ticklabel to 1 plot in normal way
  4042. ax[0].set_xticklabels(('a', 'b', 'c', 'd'))
  4043. ax[0].set_yticklabels(('11', '12', '13', '14'))
  4044. # set ticklabel to the other plot, expect the 2 plots have same label
  4045. # setting pass get_ticklabels return value as ticklabels argument
  4046. ax[1].set_xticklabels(ax[0].get_xticklabels())
  4047. ax[1].set_yticklabels(ax[0].get_yticklabels())
  4048. @image_comparison(['retain_tick_visibility.png'])
  4049. def test_retain_tick_visibility():
  4050. fig, ax = plt.subplots()
  4051. plt.plot([0, 1, 2], [0, -1, 4])
  4052. plt.setp(ax.get_yticklabels(), visible=False)
  4053. ax.tick_params(axis="y", which="both", length=0)
  4054. def test_tick_label_update():
  4055. # test issue 9397
  4056. fig, ax = plt.subplots()
  4057. # Set up a dummy formatter
  4058. def formatter_func(x, pos):
  4059. return "unit value" if x == 1 else ""
  4060. ax.xaxis.set_major_formatter(plt.FuncFormatter(formatter_func))
  4061. # Force some of the x-axis ticks to be outside of the drawn range
  4062. ax.set_xticks([-1, 0, 1, 2, 3])
  4063. ax.set_xlim(-0.5, 2.5)
  4064. ax.figure.canvas.draw()
  4065. tick_texts = [tick.get_text() for tick in ax.xaxis.get_ticklabels()]
  4066. assert tick_texts == ["", "", "unit value", "", ""]
  4067. @image_comparison(['o_marker_path_snap.png'], savefig_kwarg={'dpi': 72})
  4068. def test_o_marker_path_snap():
  4069. fig, ax = plt.subplots()
  4070. ax.margins(.1)
  4071. for ms in range(1, 15):
  4072. ax.plot([1, 2, ], np.ones(2) + ms, 'o', ms=ms)
  4073. for ms in np.linspace(1, 10, 25):
  4074. ax.plot([3, 4, ], np.ones(2) + ms, 'o', ms=ms)
  4075. def test_margins():
  4076. # test all ways margins can be called
  4077. data = [1, 10]
  4078. xmin = 0.0
  4079. xmax = len(data) - 1.0
  4080. ymin = min(data)
  4081. ymax = max(data)
  4082. fig1, ax1 = plt.subplots(1, 1)
  4083. ax1.plot(data)
  4084. ax1.margins(1)
  4085. assert ax1.margins() == (1, 1)
  4086. assert ax1.get_xlim() == (xmin - (xmax - xmin) * 1,
  4087. xmax + (xmax - xmin) * 1)
  4088. assert ax1.get_ylim() == (ymin - (ymax - ymin) * 1,
  4089. ymax + (ymax - ymin) * 1)
  4090. fig2, ax2 = plt.subplots(1, 1)
  4091. ax2.plot(data)
  4092. ax2.margins(0.5, 2)
  4093. assert ax2.margins() == (0.5, 2)
  4094. assert ax2.get_xlim() == (xmin - (xmax - xmin) * 0.5,
  4095. xmax + (xmax - xmin) * 0.5)
  4096. assert ax2.get_ylim() == (ymin - (ymax - ymin) * 2,
  4097. ymax + (ymax - ymin) * 2)
  4098. fig3, ax3 = plt.subplots(1, 1)
  4099. ax3.plot(data)
  4100. ax3.margins(x=-0.2, y=0.5)
  4101. assert ax3.margins() == (-0.2, 0.5)
  4102. assert ax3.get_xlim() == (xmin - (xmax - xmin) * -0.2,
  4103. xmax + (xmax - xmin) * -0.2)
  4104. assert ax3.get_ylim() == (ymin - (ymax - ymin) * 0.5,
  4105. ymax + (ymax - ymin) * 0.5)
  4106. def test_length_one_hist():
  4107. fig, ax = plt.subplots()
  4108. ax.hist(1)
  4109. ax.hist([1])
  4110. def test_pathological_hexbin():
  4111. # issue #2863
  4112. out = io.BytesIO()
  4113. with warnings.catch_warnings(record=True) as w:
  4114. warnings.simplefilter("always")
  4115. mylist = [10] * 100
  4116. fig, ax = plt.subplots(1, 1)
  4117. ax.hexbin(mylist, mylist)
  4118. fig.savefig(out)
  4119. assert len(w) == 0
  4120. def test_color_None():
  4121. # issue 3855
  4122. fig, ax = plt.subplots()
  4123. ax.plot([1, 2], [1, 2], color=None)
  4124. def test_color_alias():
  4125. # issues 4157 and 4162
  4126. fig, ax = plt.subplots()
  4127. line = ax.plot([0, 1], c='lime')[0]
  4128. assert 'lime' == line.get_color()
  4129. def test_numerical_hist_label():
  4130. fig, ax = plt.subplots()
  4131. ax.hist([range(15)] * 5, label=range(5))
  4132. ax.legend()
  4133. def test_unicode_hist_label():
  4134. fig, ax = plt.subplots()
  4135. a = (b'\xe5\xbe\x88\xe6\xbc\x82\xe4\xba\xae, ' +
  4136. b'r\xc3\xb6m\xc3\xa4n ch\xc3\xa4r\xc3\xa1ct\xc3\xa8rs')
  4137. b = b'\xd7\xa9\xd7\x9c\xd7\x95\xd7\x9d'
  4138. labels = [a.decode('utf-8'),
  4139. 'hi aardvark',
  4140. b.decode('utf-8'),
  4141. ]
  4142. ax.hist([range(15)] * 3, label=labels)
  4143. ax.legend()
  4144. def test_move_offsetlabel():
  4145. data = np.random.random(10) * 1e-22
  4146. fig, ax = plt.subplots()
  4147. ax.plot(data)
  4148. ax.yaxis.tick_right()
  4149. assert (1, 0.5) == ax.yaxis.offsetText.get_position()
  4150. @image_comparison(['rc_spines.png'], savefig_kwarg={'dpi': 40})
  4151. def test_rc_spines():
  4152. rc_dict = {
  4153. 'axes.spines.left': False,
  4154. 'axes.spines.right': False,
  4155. 'axes.spines.top': False,
  4156. 'axes.spines.bottom': False}
  4157. with matplotlib.rc_context(rc_dict):
  4158. fig, ax = plt.subplots()
  4159. @image_comparison(['rc_grid.png'], savefig_kwarg={'dpi': 40})
  4160. def test_rc_grid():
  4161. fig = plt.figure()
  4162. rc_dict0 = {
  4163. 'axes.grid': True,
  4164. 'axes.grid.axis': 'both'
  4165. }
  4166. rc_dict1 = {
  4167. 'axes.grid': True,
  4168. 'axes.grid.axis': 'x'
  4169. }
  4170. rc_dict2 = {
  4171. 'axes.grid': True,
  4172. 'axes.grid.axis': 'y'
  4173. }
  4174. dict_list = [rc_dict0, rc_dict1, rc_dict2]
  4175. for i, rc_dict in enumerate(dict_list, 1):
  4176. with matplotlib.rc_context(rc_dict):
  4177. fig.add_subplot(3, 1, i)
  4178. def test_rc_tick():
  4179. d = {'xtick.bottom': False, 'xtick.top': True,
  4180. 'ytick.left': True, 'ytick.right': False}
  4181. with plt.rc_context(rc=d):
  4182. fig = plt.figure()
  4183. ax1 = fig.add_subplot(1, 1, 1)
  4184. xax = ax1.xaxis
  4185. yax = ax1.yaxis
  4186. # tick1On bottom/left
  4187. assert not xax._major_tick_kw['tick1On']
  4188. assert xax._major_tick_kw['tick2On']
  4189. assert not xax._minor_tick_kw['tick1On']
  4190. assert xax._minor_tick_kw['tick2On']
  4191. assert yax._major_tick_kw['tick1On']
  4192. assert not yax._major_tick_kw['tick2On']
  4193. assert yax._minor_tick_kw['tick1On']
  4194. assert not yax._minor_tick_kw['tick2On']
  4195. def test_rc_major_minor_tick():
  4196. d = {'xtick.top': True, 'ytick.right': True, # Enable all ticks
  4197. 'xtick.bottom': True, 'ytick.left': True,
  4198. # Selectively disable
  4199. 'xtick.minor.bottom': False, 'xtick.major.bottom': False,
  4200. 'ytick.major.left': False, 'ytick.minor.left': False}
  4201. with plt.rc_context(rc=d):
  4202. fig = plt.figure()
  4203. ax1 = fig.add_subplot(1, 1, 1)
  4204. xax = ax1.xaxis
  4205. yax = ax1.yaxis
  4206. # tick1On bottom/left
  4207. assert not xax._major_tick_kw['tick1On']
  4208. assert xax._major_tick_kw['tick2On']
  4209. assert not xax._minor_tick_kw['tick1On']
  4210. assert xax._minor_tick_kw['tick2On']
  4211. assert not yax._major_tick_kw['tick1On']
  4212. assert yax._major_tick_kw['tick2On']
  4213. assert not yax._minor_tick_kw['tick1On']
  4214. assert yax._minor_tick_kw['tick2On']
  4215. def test_square_plot():
  4216. x = np.arange(4)
  4217. y = np.array([1., 3., 5., 7.])
  4218. fig, ax = plt.subplots()
  4219. ax.plot(x, y, 'mo')
  4220. ax.axis('square')
  4221. xlim, ylim = ax.get_xlim(), ax.get_ylim()
  4222. assert np.diff(xlim) == np.diff(ylim)
  4223. assert ax.get_aspect() == 'equal'
  4224. assert_array_almost_equal(
  4225. ax.get_position(original=True).extents,
  4226. np.array((0.125, 0.1, 0.9, 0.9)))
  4227. assert_array_almost_equal(
  4228. ax.get_position(original=False).extents,
  4229. np.array((0.2125, 0.1, 0.8125, 0.9)))
  4230. def test_no_None():
  4231. fig, ax = plt.subplots()
  4232. with pytest.raises(ValueError):
  4233. plt.plot(None)
  4234. with pytest.raises(ValueError):
  4235. plt.plot(None, None)
  4236. @pytest.mark.parametrize(
  4237. "xy, cls", [
  4238. ((), mpl.image.AxesImage), # (0, N)
  4239. (((3, 7), (2, 6)), mpl.image.AxesImage), # (xmin, xmax)
  4240. ((range(5), range(4)), mpl.image.AxesImage), # regular grid
  4241. (([1, 2, 4, 8, 16], [0, 1, 2, 3]), # irregular grid
  4242. mpl.image.PcolorImage),
  4243. ((np.random.random((4, 5)), np.random.random((4, 5))), # 2D coords
  4244. mpl.collections.QuadMesh),
  4245. ]
  4246. )
  4247. @pytest.mark.parametrize(
  4248. "data", [np.arange(12).reshape((3, 4)), np.random.rand(3, 4, 3)]
  4249. )
  4250. def test_pcolorfast(xy, data, cls):
  4251. fig, ax = plt.subplots()
  4252. assert type(ax.pcolorfast(*xy, data)) == cls
  4253. def test_shared_scale():
  4254. fig, axs = plt.subplots(2, 2, sharex=True, sharey=True)
  4255. axs[0, 0].set_xscale("log")
  4256. axs[0, 0].set_yscale("log")
  4257. for ax in axs.flat:
  4258. assert ax.get_yscale() == 'log'
  4259. assert ax.get_xscale() == 'log'
  4260. axs[1, 1].set_xscale("linear")
  4261. axs[1, 1].set_yscale("linear")
  4262. for ax in axs.flat:
  4263. assert ax.get_yscale() == 'linear'
  4264. assert ax.get_xscale() == 'linear'
  4265. def test_violin_point_mass():
  4266. """Violin plot should handle point mass pdf gracefully."""
  4267. plt.violinplot(np.array([0, 0]))
  4268. def generate_errorbar_inputs():
  4269. base_xy = cycler('x', [np.arange(5)]) + cycler('y', [np.ones(5)])
  4270. err_cycler = cycler('err', [1,
  4271. [1, 1, 1, 1, 1],
  4272. [[1, 1, 1, 1, 1],
  4273. [1, 1, 1, 1, 1]],
  4274. [[1]] * 5,
  4275. np.ones(5),
  4276. np.ones((2, 5)),
  4277. np.ones((5, 1)),
  4278. None
  4279. ])
  4280. xerr_cy = cycler('xerr', err_cycler)
  4281. yerr_cy = cycler('yerr', err_cycler)
  4282. empty = ((cycler('x', [[]]) + cycler('y', [[]])) *
  4283. cycler('xerr', [[], None]) * cycler('yerr', [[], None]))
  4284. xerr_only = base_xy * xerr_cy
  4285. yerr_only = base_xy * yerr_cy
  4286. both_err = base_xy * yerr_cy * xerr_cy
  4287. return [*xerr_only, *yerr_only, *both_err, *empty]
  4288. @pytest.mark.parametrize('kwargs', generate_errorbar_inputs())
  4289. def test_errorbar_inputs_shotgun(kwargs):
  4290. # (n, 1)-shaped error deprecation already tested by test_errorbar.
  4291. with mpl.cbook._suppress_matplotlib_deprecation_warning():
  4292. ax = plt.gca()
  4293. eb = ax.errorbar(**kwargs)
  4294. eb.remove()
  4295. @image_comparison(["dash_offset"], remove_text=True)
  4296. def test_dash_offset():
  4297. fig, ax = plt.subplots()
  4298. x = np.linspace(0, 10)
  4299. y = np.ones_like(x)
  4300. for j in range(0, 100, 2):
  4301. ax.plot(x, j*y, ls=(j, (10, 10)), lw=5, color='k')
  4302. def test_title_pad():
  4303. # check that title padding puts the title in the right
  4304. # place...
  4305. fig, ax = plt.subplots()
  4306. ax.set_title('aardvark', pad=30.)
  4307. m = ax.titleOffsetTrans.get_matrix()
  4308. assert m[1, -1] == (30. / 72. * fig.dpi)
  4309. ax.set_title('aardvark', pad=0.)
  4310. m = ax.titleOffsetTrans.get_matrix()
  4311. assert m[1, -1] == 0.
  4312. # check that it is reverted...
  4313. ax.set_title('aardvark', pad=None)
  4314. m = ax.titleOffsetTrans.get_matrix()
  4315. assert m[1, -1] == (matplotlib.rcParams['axes.titlepad'] / 72. * fig.dpi)
  4316. def test_title_location_roundtrip():
  4317. fig, ax = plt.subplots()
  4318. # set default title location
  4319. plt.rcParams['axes.titlelocation'] = 'center'
  4320. ax.set_title('aardvark')
  4321. ax.set_title('left', loc='left')
  4322. ax.set_title('right', loc='right')
  4323. assert 'left' == ax.get_title(loc='left')
  4324. assert 'right' == ax.get_title(loc='right')
  4325. assert 'aardvark' == ax.get_title(loc='center')
  4326. with pytest.raises(ValueError):
  4327. ax.get_title(loc='foo')
  4328. with pytest.raises(ValueError):
  4329. ax.set_title('fail', loc='foo')
  4330. @image_comparison(["loglog.png"], remove_text=True, tol=0.02)
  4331. def test_loglog():
  4332. fig, ax = plt.subplots()
  4333. x = np.arange(1, 11)
  4334. ax.loglog(x, x**3, lw=5)
  4335. ax.tick_params(length=25, width=2)
  4336. ax.tick_params(length=15, width=2, which='minor')
  4337. @image_comparison(["test_loglog_nonpos.png"], remove_text=True, style='mpl20')
  4338. def test_loglog_nonpos():
  4339. fig, ax = plt.subplots(3, 3)
  4340. x = np.arange(1, 11)
  4341. y = x**3
  4342. y[7] = -3.
  4343. x[4] = -10
  4344. for nn, mcx in enumerate(['mask', 'clip', '']):
  4345. for mm, mcy in enumerate(['mask', 'clip', '']):
  4346. kws = {}
  4347. if mcx:
  4348. kws['nonposx'] = mcx
  4349. if mcy:
  4350. kws['nonposy'] = mcy
  4351. ax[mm, nn].loglog(x, y**3, lw=2, **kws)
  4352. @pytest.mark.style('default')
  4353. def test_axes_margins():
  4354. fig, ax = plt.subplots()
  4355. ax.plot([0, 1, 2, 3])
  4356. assert ax.get_ybound()[0] != 0
  4357. fig, ax = plt.subplots()
  4358. ax.bar([0, 1, 2, 3], [1, 1, 1, 1])
  4359. assert ax.get_ybound()[0] == 0
  4360. fig, ax = plt.subplots()
  4361. ax.barh([0, 1, 2, 3], [1, 1, 1, 1])
  4362. assert ax.get_xbound()[0] == 0
  4363. fig, ax = plt.subplots()
  4364. ax.pcolor(np.zeros((10, 10)))
  4365. assert ax.get_xbound() == (0, 10)
  4366. assert ax.get_ybound() == (0, 10)
  4367. fig, ax = plt.subplots()
  4368. ax.pcolorfast(np.zeros((10, 10)))
  4369. assert ax.get_xbound() == (0, 10)
  4370. assert ax.get_ybound() == (0, 10)
  4371. fig, ax = plt.subplots()
  4372. ax.hist(np.arange(10))
  4373. assert ax.get_ybound()[0] == 0
  4374. fig, ax = plt.subplots()
  4375. ax.imshow(np.zeros((10, 10)))
  4376. assert ax.get_xbound() == (-0.5, 9.5)
  4377. assert ax.get_ybound() == (-0.5, 9.5)
  4378. @pytest.fixture(params=['x', 'y'])
  4379. def shared_axis_remover(request):
  4380. def _helper_x(ax):
  4381. ax2 = ax.twinx()
  4382. ax2.remove()
  4383. ax.set_xlim(0, 15)
  4384. r = ax.xaxis.get_major_locator()()
  4385. assert r[-1] > 14
  4386. def _helper_y(ax):
  4387. ax2 = ax.twiny()
  4388. ax2.remove()
  4389. ax.set_ylim(0, 15)
  4390. r = ax.yaxis.get_major_locator()()
  4391. assert r[-1] > 14
  4392. return {"x": _helper_x, "y": _helper_y}[request.param]
  4393. @pytest.fixture(params=['gca', 'subplots', 'subplots_shared', 'add_axes'])
  4394. def shared_axes_generator(request):
  4395. # test all of the ways to get fig/ax sets
  4396. if request.param == 'gca':
  4397. fig = plt.figure()
  4398. ax = fig.gca()
  4399. elif request.param == 'subplots':
  4400. fig, ax = plt.subplots()
  4401. elif request.param == 'subplots_shared':
  4402. fig, ax_lst = plt.subplots(2, 2, sharex='all', sharey='all')
  4403. ax = ax_lst[0][0]
  4404. elif request.param == 'add_axes':
  4405. fig = plt.figure()
  4406. ax = fig.add_axes([.1, .1, .8, .8])
  4407. return fig, ax
  4408. def test_remove_shared_axes(shared_axes_generator, shared_axis_remover):
  4409. # test all of the ways to get fig/ax sets
  4410. fig, ax = shared_axes_generator
  4411. shared_axis_remover(ax)
  4412. def test_remove_shared_axes_relim():
  4413. fig, ax_lst = plt.subplots(2, 2, sharex='all', sharey='all')
  4414. ax = ax_lst[0][0]
  4415. orig_xlim = ax_lst[0][1].get_xlim()
  4416. ax.remove()
  4417. ax.set_xlim(0, 5)
  4418. assert_array_equal(ax_lst[0][1].get_xlim(), orig_xlim)
  4419. def test_shared_axes_autoscale():
  4420. l = np.arange(-80, 90, 40)
  4421. t = np.random.random_sample((l.size, l.size))
  4422. ax1 = plt.subplot(211)
  4423. ax1.set_xlim(-1000, 1000)
  4424. ax1.set_ylim(-1000, 1000)
  4425. ax1.contour(l, l, t)
  4426. ax2 = plt.subplot(212, sharex=ax1, sharey=ax1)
  4427. ax2.contour(l, l, t)
  4428. assert not ax1.get_autoscalex_on() and not ax2.get_autoscalex_on()
  4429. assert not ax1.get_autoscaley_on() and not ax2.get_autoscaley_on()
  4430. assert ax1.get_xlim() == ax2.get_xlim() == (-1000, 1000)
  4431. assert ax1.get_ylim() == ax2.get_ylim() == (-1000, 1000)
  4432. def test_adjust_numtick_aspect():
  4433. fig, ax = plt.subplots()
  4434. ax.yaxis.get_major_locator().set_params(nbins='auto')
  4435. ax.set_xlim(0, 1000)
  4436. ax.set_aspect('equal')
  4437. fig.canvas.draw()
  4438. assert len(ax.yaxis.get_major_locator()()) == 2
  4439. ax.set_ylim(0, 1000)
  4440. fig.canvas.draw()
  4441. assert len(ax.yaxis.get_major_locator()()) > 2
  4442. @image_comparison(["auto_numticks.png"], style='default')
  4443. def test_auto_numticks():
  4444. # Make tiny, empty subplots, verify that there are only 3 ticks.
  4445. fig, axs = plt.subplots(4, 4)
  4446. @image_comparison(["auto_numticks_log.png"], style='default')
  4447. def test_auto_numticks_log():
  4448. # Verify that there are not too many ticks with a large log range.
  4449. fig, ax = plt.subplots()
  4450. matplotlib.rcParams['axes.autolimit_mode'] = 'round_numbers'
  4451. ax.loglog([1e-20, 1e5], [1e-16, 10])
  4452. def test_broken_barh_empty():
  4453. fig, ax = plt.subplots()
  4454. ax.broken_barh([], (.1, .5))
  4455. def test_broken_barh_timedelta():
  4456. """Check that timedelta works as x, dx pair for this method."""
  4457. fig, ax = plt.subplots()
  4458. pp = ax.broken_barh([(datetime.datetime(2018, 11, 9, 0, 0, 0),
  4459. datetime.timedelta(hours=1))], [1, 2])
  4460. assert pp.get_paths()[0].vertices[0, 0] == 737007.0
  4461. assert pp.get_paths()[0].vertices[2, 0] == 737007.0 + 1 / 24
  4462. def test_pandas_pcolormesh(pd):
  4463. time = pd.date_range('2000-01-01', periods=10)
  4464. depth = np.arange(20)
  4465. data = np.random.rand(20, 10)
  4466. fig, ax = plt.subplots()
  4467. ax.pcolormesh(time, depth, data)
  4468. def test_pandas_indexing_dates(pd):
  4469. dates = np.arange('2005-02', '2005-03', dtype='datetime64[D]')
  4470. values = np.sin(np.array(range(len(dates))))
  4471. df = pd.DataFrame({'dates': dates, 'values': values})
  4472. ax = plt.gca()
  4473. without_zero_index = df[np.array(df.index) % 2 == 1].copy()
  4474. ax.plot('dates', 'values', data=without_zero_index)
  4475. def test_pandas_errorbar_indexing(pd):
  4476. df = pd.DataFrame(np.random.uniform(size=(5, 4)),
  4477. columns=['x', 'y', 'xe', 'ye'],
  4478. index=[1, 2, 3, 4, 5])
  4479. fig, ax = plt.subplots()
  4480. ax.errorbar('x', 'y', xerr='xe', yerr='ye', data=df)
  4481. def test_pandas_index_shape(pd):
  4482. df = pd.DataFrame({"XX": [4, 5, 6], "YY": [7, 1, 2]})
  4483. fig, ax = plt.subplots()
  4484. ax.plot(df.index, df['YY'])
  4485. def test_pandas_indexing_hist(pd):
  4486. ser_1 = pd.Series(data=[1, 2, 2, 3, 3, 4, 4, 4, 4, 5])
  4487. ser_2 = ser_1.iloc[1:]
  4488. fig, ax = plt.subplots()
  4489. ax.hist(ser_2)
  4490. def test_pandas_bar_align_center(pd):
  4491. # Tests fix for issue 8767
  4492. df = pd.DataFrame({'a': range(2), 'b': range(2)})
  4493. fig, ax = plt.subplots(1)
  4494. ax.bar(df.loc[df['a'] == 1, 'b'],
  4495. df.loc[df['a'] == 1, 'b'],
  4496. align='center')
  4497. fig.canvas.draw()
  4498. def test_axis_set_tick_params_labelsize_labelcolor():
  4499. # Tests fix for issue 4346
  4500. axis_1 = plt.subplot()
  4501. axis_1.yaxis.set_tick_params(labelsize=30, labelcolor='red',
  4502. direction='out')
  4503. # Expected values after setting the ticks
  4504. assert axis_1.yaxis.majorTicks[0]._size == 4.0
  4505. assert axis_1.yaxis.majorTicks[0]._color == 'k'
  4506. assert axis_1.yaxis.majorTicks[0]._labelsize == 30.0
  4507. assert axis_1.yaxis.majorTicks[0]._labelcolor == 'red'
  4508. def test_axes_tick_params_gridlines():
  4509. # Now treating grid params like other Tick params
  4510. ax = plt.subplot()
  4511. ax.tick_params(grid_color='b', grid_linewidth=5, grid_alpha=0.5,
  4512. grid_linestyle='dashdot')
  4513. for axis in ax.xaxis, ax.yaxis:
  4514. assert axis.majorTicks[0]._grid_color == 'b'
  4515. assert axis.majorTicks[0]._grid_linewidth == 5
  4516. assert axis.majorTicks[0]._grid_alpha == 0.5
  4517. assert axis.majorTicks[0]._grid_linestyle == 'dashdot'
  4518. def test_axes_tick_params_ylabelside():
  4519. # Tests fix for issue 10267
  4520. ax = plt.subplot()
  4521. ax.tick_params(labelleft=False, labelright=True,
  4522. which='major')
  4523. ax.tick_params(labelleft=False, labelright=True,
  4524. which='minor')
  4525. # expects left false, right true
  4526. assert ax.yaxis.majorTicks[0].label1.get_visible() is False
  4527. assert ax.yaxis.majorTicks[0].label2.get_visible() is True
  4528. assert ax.yaxis.minorTicks[0].label1.get_visible() is False
  4529. assert ax.yaxis.minorTicks[0].label2.get_visible() is True
  4530. def test_axes_tick_params_xlabelside():
  4531. # Tests fix for issue 10267
  4532. ax = plt.subplot()
  4533. ax.tick_params(labeltop=True, labelbottom=False,
  4534. which='major')
  4535. ax.tick_params(labeltop=True, labelbottom=False,
  4536. which='minor')
  4537. # expects top True, bottom False
  4538. # label1.get_visible() mapped to labelbottom
  4539. # label2.get_visible() mapped to labeltop
  4540. assert ax.xaxis.majorTicks[0].label1.get_visible() is False
  4541. assert ax.xaxis.majorTicks[0].label2.get_visible() is True
  4542. assert ax.xaxis.minorTicks[0].label1.get_visible() is False
  4543. assert ax.xaxis.minorTicks[0].label2.get_visible() is True
  4544. def test_none_kwargs():
  4545. ax = plt.figure().subplots()
  4546. ln, = ax.plot(range(32), linestyle=None)
  4547. assert ln.get_linestyle() == '-'
  4548. def test_ls_ds_conflict():
  4549. # Passing the drawstyle with the linestyle is deprecated since 3.1.
  4550. # We still need to test this until it's removed from the code.
  4551. # But we don't want to see the deprecation warning in the test.
  4552. with matplotlib.cbook._suppress_matplotlib_deprecation_warning(), \
  4553. pytest.raises(ValueError):
  4554. plt.plot(range(32), linestyle='steps-pre:', drawstyle='steps-post')
  4555. def test_bar_uint8():
  4556. xs = [0, 1, 2, 3]
  4557. b = plt.bar(np.array(xs, dtype=np.uint8), [2, 3, 4, 5], align="edge")
  4558. for (patch, x) in zip(b.patches, xs):
  4559. assert patch.xy[0] == x
  4560. @image_comparison(['date_timezone_x.png'])
  4561. def test_date_timezone_x():
  4562. # Tests issue 5575
  4563. time_index = [datetime.datetime(2016, 2, 22, hour=x,
  4564. tzinfo=dutz.gettz('Canada/Eastern'))
  4565. for x in range(3)]
  4566. # Same Timezone
  4567. plt.figure(figsize=(20, 12))
  4568. plt.subplot(2, 1, 1)
  4569. plt.plot_date(time_index, [3] * 3, tz='Canada/Eastern')
  4570. # Different Timezone
  4571. plt.subplot(2, 1, 2)
  4572. plt.plot_date(time_index, [3] * 3, tz='UTC')
  4573. @image_comparison(['date_timezone_y.png'])
  4574. def test_date_timezone_y():
  4575. # Tests issue 5575
  4576. time_index = [datetime.datetime(2016, 2, 22, hour=x,
  4577. tzinfo=dutz.gettz('Canada/Eastern'))
  4578. for x in range(3)]
  4579. # Same Timezone
  4580. plt.figure(figsize=(20, 12))
  4581. plt.subplot(2, 1, 1)
  4582. plt.plot_date([3] * 3,
  4583. time_index, tz='Canada/Eastern', xdate=False, ydate=True)
  4584. # Different Timezone
  4585. plt.subplot(2, 1, 2)
  4586. plt.plot_date([3] * 3, time_index, tz='UTC', xdate=False, ydate=True)
  4587. @image_comparison(['date_timezone_x_and_y.png'])
  4588. def test_date_timezone_x_and_y():
  4589. # Tests issue 5575
  4590. UTC = datetime.timezone.utc
  4591. time_index = [datetime.datetime(2016, 2, 22, hour=x, tzinfo=UTC)
  4592. for x in range(3)]
  4593. # Same Timezone
  4594. plt.figure(figsize=(20, 12))
  4595. plt.subplot(2, 1, 1)
  4596. plt.plot_date(time_index, time_index, tz='UTC', ydate=True)
  4597. # Different Timezone
  4598. plt.subplot(2, 1, 2)
  4599. plt.plot_date(time_index, time_index, tz='US/Eastern', ydate=True)
  4600. @image_comparison(['axisbelow.png'], remove_text=True)
  4601. def test_axisbelow():
  4602. # Test 'line' setting added in 6287.
  4603. # Show only grids, not frame or ticks, to make this test
  4604. # independent of future change to drawing order of those elements.
  4605. axs = plt.figure().subplots(ncols=3, sharex=True, sharey=True)
  4606. settings = (False, 'line', True)
  4607. for ax, setting in zip(axs, settings):
  4608. ax.plot((0, 10), (0, 10), lw=10, color='m')
  4609. circ = mpatches.Circle((3, 3), color='r')
  4610. ax.add_patch(circ)
  4611. ax.grid(color='c', linestyle='-', linewidth=3)
  4612. ax.tick_params(top=False, bottom=False,
  4613. left=False, right=False)
  4614. for spine in ax.spines.values():
  4615. spine.set_visible(False)
  4616. ax.set_axisbelow(setting)
  4617. @image_comparison(['titletwiny.png'], style='mpl20')
  4618. def test_titletwiny():
  4619. # Remove this line when this test image is regenerated.
  4620. plt.rcParams['text.kerning_factor'] = 6
  4621. # Test that title is put above xlabel if xlabel at top
  4622. fig, ax = plt.subplots()
  4623. fig.subplots_adjust(top=0.8)
  4624. ax2 = ax.twiny()
  4625. ax.set_xlabel('Xlabel')
  4626. ax2.set_xlabel('Xlabel2')
  4627. ax.set_title('Title')
  4628. def test_titlesetpos():
  4629. # Test that title stays put if we set it manually
  4630. fig, ax = plt.subplots()
  4631. fig.subplots_adjust(top=0.8)
  4632. ax2 = ax.twiny()
  4633. ax.set_xlabel('Xlabel')
  4634. ax2.set_xlabel('Xlabel2')
  4635. ax.set_title('Title')
  4636. pos = (0.5, 1.11)
  4637. ax.title.set_position(pos)
  4638. renderer = fig.canvas.get_renderer()
  4639. ax._update_title_position(renderer)
  4640. assert ax.title.get_position() == pos
  4641. def test_title_xticks_top():
  4642. # Test that title moves if xticks on top of axes.
  4643. fig, ax = plt.subplots()
  4644. ax.xaxis.set_ticks_position('top')
  4645. ax.set_title('xlabel top')
  4646. fig.canvas.draw()
  4647. assert ax.title.get_position()[1] > 1.04
  4648. def test_title_xticks_top_both():
  4649. # Test that title moves if xticks on top of axes.
  4650. fig, ax = plt.subplots()
  4651. ax.tick_params(axis="x", bottom=True, top=True,
  4652. labelbottom=True, labeltop=True)
  4653. ax.set_title('xlabel top')
  4654. fig.canvas.draw()
  4655. assert ax.title.get_position()[1] > 1.04
  4656. def test_offset_label_color():
  4657. # Tests issue 6440
  4658. fig = plt.figure()
  4659. ax = fig.add_subplot(1, 1, 1)
  4660. ax.plot([1.01e9, 1.02e9, 1.03e9])
  4661. ax.yaxis.set_tick_params(labelcolor='red')
  4662. assert ax.yaxis.get_offset_text().get_color() == 'red'
  4663. def test_large_offset():
  4664. fig, ax = plt.subplots()
  4665. ax.plot((1 + np.array([0, 1.e-12])) * 1.e27)
  4666. fig.canvas.draw()
  4667. def test_barb_units():
  4668. fig, ax = plt.subplots()
  4669. dates = [datetime.datetime(2017, 7, 15, 18, i) for i in range(0, 60, 10)]
  4670. y = np.linspace(0, 5, len(dates))
  4671. u = v = np.linspace(0, 50, len(dates))
  4672. ax.barbs(dates, y, u, v)
  4673. def test_quiver_units():
  4674. fig, ax = plt.subplots()
  4675. dates = [datetime.datetime(2017, 7, 15, 18, i) for i in range(0, 60, 10)]
  4676. y = np.linspace(0, 5, len(dates))
  4677. u = v = np.linspace(0, 50, len(dates))
  4678. ax.quiver(dates, y, u, v)
  4679. def test_bar_color_cycle():
  4680. to_rgb = mcolors.to_rgb
  4681. fig, ax = plt.subplots()
  4682. for j in range(5):
  4683. ln, = ax.plot(range(3))
  4684. brs = ax.bar(range(3), range(3))
  4685. for br in brs:
  4686. assert to_rgb(ln.get_color()) == to_rgb(br.get_facecolor())
  4687. def test_tick_param_label_rotation():
  4688. fix, (ax, ax2) = plt.subplots(1, 2)
  4689. ax.plot([0, 1], [0, 1])
  4690. ax2.plot([0, 1], [0, 1])
  4691. ax.xaxis.set_tick_params(which='both', rotation=75)
  4692. ax.yaxis.set_tick_params(which='both', rotation=90)
  4693. for text in ax.get_xticklabels(which='both'):
  4694. assert text.get_rotation() == 75
  4695. for text in ax.get_yticklabels(which='both'):
  4696. assert text.get_rotation() == 90
  4697. ax2.tick_params(axis='x', labelrotation=53)
  4698. ax2.tick_params(axis='y', rotation=35)
  4699. for text in ax2.get_xticklabels(which='major'):
  4700. assert text.get_rotation() == 53
  4701. for text in ax2.get_yticklabels(which='major'):
  4702. assert text.get_rotation() == 35
  4703. @pytest.mark.style('default')
  4704. def test_fillbetween_cycle():
  4705. fig, ax = plt.subplots()
  4706. for j in range(3):
  4707. cc = ax.fill_between(range(3), range(3))
  4708. target = mcolors.to_rgba('C{}'.format(j))
  4709. assert tuple(cc.get_facecolors().squeeze()) == tuple(target)
  4710. for j in range(3, 6):
  4711. cc = ax.fill_betweenx(range(3), range(3))
  4712. target = mcolors.to_rgba('C{}'.format(j))
  4713. assert tuple(cc.get_facecolors().squeeze()) == tuple(target)
  4714. target = mcolors.to_rgba('k')
  4715. for al in ['facecolor', 'facecolors', 'color']:
  4716. cc = ax.fill_between(range(3), range(3), **{al: 'k'})
  4717. assert tuple(cc.get_facecolors().squeeze()) == tuple(target)
  4718. edge_target = mcolors.to_rgba('k')
  4719. for j, el in enumerate(['edgecolor', 'edgecolors'], start=6):
  4720. cc = ax.fill_between(range(3), range(3), **{el: 'k'})
  4721. face_target = mcolors.to_rgba('C{}'.format(j))
  4722. assert tuple(cc.get_facecolors().squeeze()) == tuple(face_target)
  4723. assert tuple(cc.get_edgecolors().squeeze()) == tuple(edge_target)
  4724. def test_log_margins():
  4725. plt.rcParams['axes.autolimit_mode'] = 'data'
  4726. fig, ax = plt.subplots()
  4727. margin = 0.05
  4728. ax.set_xmargin(margin)
  4729. ax.semilogx([10, 100], [10, 100])
  4730. xlim0, xlim1 = ax.get_xlim()
  4731. transform = ax.xaxis.get_transform()
  4732. xlim0t, xlim1t = transform.transform([xlim0, xlim1])
  4733. x0t, x1t = transform.transform([10, 100])
  4734. delta = (x1t - x0t) * margin
  4735. assert_allclose([xlim0t + delta, xlim1t - delta], [x0t, x1t])
  4736. def test_color_length_mismatch():
  4737. N = 5
  4738. x, y = np.arange(N), np.arange(N)
  4739. colors = np.arange(N+1)
  4740. fig, ax = plt.subplots()
  4741. with pytest.raises(ValueError):
  4742. ax.scatter(x, y, c=colors)
  4743. c_rgb = (0.5, 0.5, 0.5)
  4744. ax.scatter(x, y, c=c_rgb)
  4745. ax.scatter(x, y, c=[c_rgb] * N)
  4746. def test_eventplot_legend():
  4747. plt.eventplot([1.0], label='Label')
  4748. plt.legend()
  4749. def test_bar_broadcast_args():
  4750. fig, ax = plt.subplots()
  4751. # Check that a bar chart with a single height for all bars works.
  4752. ax.bar(range(4), 1)
  4753. # Check that a horizontal chart with one width works.
  4754. ax.bar(0, 1, bottom=range(4), width=1, orientation='horizontal')
  4755. # Check that edgecolor gets broadcast.
  4756. rect1, rect2 = ax.bar([0, 1], [0, 1], edgecolor=(.1, .2, .3, .4))
  4757. assert rect1.get_edgecolor() == rect2.get_edgecolor() == (.1, .2, .3, .4)
  4758. def test_invalid_axis_limits():
  4759. plt.plot([0, 1], [0, 1])
  4760. with pytest.raises(ValueError):
  4761. plt.xlim(np.nan)
  4762. with pytest.raises(ValueError):
  4763. plt.xlim(np.inf)
  4764. with pytest.raises(ValueError):
  4765. plt.ylim(np.nan)
  4766. with pytest.raises(ValueError):
  4767. plt.ylim(np.inf)
  4768. # Test all 4 combinations of logs/symlogs for minorticks_on()
  4769. @pytest.mark.parametrize('xscale', ['symlog', 'log'])
  4770. @pytest.mark.parametrize('yscale', ['symlog', 'log'])
  4771. def test_minorticks_on(xscale, yscale):
  4772. ax = plt.subplot(111)
  4773. ax.plot([1, 2, 3, 4])
  4774. ax.set_xscale(xscale)
  4775. ax.set_yscale(yscale)
  4776. ax.minorticks_on()
  4777. def test_twinx_knows_limits():
  4778. fig, ax = plt.subplots()
  4779. ax.axvspan(1, 2)
  4780. xtwin = ax.twinx()
  4781. xtwin.plot([0, 0.5], [1, 2])
  4782. # control axis
  4783. fig2, ax2 = plt.subplots()
  4784. ax2.axvspan(1, 2)
  4785. ax2.plot([0, 0.5], [1, 2])
  4786. assert_array_equal(xtwin.viewLim.intervalx, ax2.viewLim.intervalx)
  4787. def test_zero_linewidth():
  4788. # Check that setting a zero linewidth doesn't error
  4789. plt.plot([0, 1], [0, 1], ls='--', lw=0)
  4790. def test_polar_gridlines():
  4791. fig = plt.figure()
  4792. ax = fig.add_subplot(111, polar=True)
  4793. # make all major grid lines lighter, only x grid lines set in 2.1.0
  4794. ax.grid(alpha=0.2)
  4795. # hide y tick labels, no effect in 2.1.0
  4796. plt.setp(ax.yaxis.get_ticklabels(), visible=False)
  4797. fig.canvas.draw()
  4798. assert ax.xaxis.majorTicks[0].gridline.get_alpha() == .2
  4799. assert ax.yaxis.majorTicks[0].gridline.get_alpha() == .2
  4800. def test_empty_errorbar_legend():
  4801. fig, ax = plt.subplots()
  4802. ax.errorbar([], [], xerr=[], label='empty y')
  4803. ax.errorbar([], [], yerr=[], label='empty x')
  4804. ax.legend()
  4805. def test_plot_columns_cycle_deprecation():
  4806. with pytest.warns(MatplotlibDeprecationWarning):
  4807. plt.plot(np.zeros((2, 2)), np.zeros((2, 3)))
  4808. @check_figures_equal(extensions=["png"])
  4809. def test_plot_decimal(fig_test, fig_ref):
  4810. x0 = np.arange(-10, 10, 0.3)
  4811. y0 = [5.2 * x ** 3 - 2.1 * x ** 2 + 7.34 * x + 4.5 for x in x0]
  4812. x = [Decimal(i) for i in x0]
  4813. y = [Decimal(i) for i in y0]
  4814. # Test image - line plot with Decimal input
  4815. fig_test.subplots().plot(x, y)
  4816. # Reference image
  4817. fig_ref.subplots().plot(x0, y0)
  4818. # pdf and svg tests fail using travis' old versions of gs and inkscape.
  4819. @check_figures_equal(extensions=["png"])
  4820. def test_markerfacecolor_none_alpha(fig_test, fig_ref):
  4821. fig_test.subplots().plot(0, "o", mfc="none", alpha=.5)
  4822. fig_ref.subplots().plot(0, "o", mfc="w", alpha=.5)
  4823. def test_tick_padding_tightbbox():
  4824. "Test that tick padding gets turned off if axis is off"
  4825. plt.rcParams["xtick.direction"] = "out"
  4826. plt.rcParams["ytick.direction"] = "out"
  4827. fig, ax = plt.subplots()
  4828. bb = ax.get_tightbbox(fig.canvas.get_renderer())
  4829. ax.axis('off')
  4830. bb2 = ax.get_tightbbox(fig.canvas.get_renderer())
  4831. assert bb.x0 < bb2.x0
  4832. assert bb.y0 < bb2.y0
  4833. def test_inset():
  4834. """
  4835. Ensure that inset_ax argument is indeed optional
  4836. """
  4837. dx, dy = 0.05, 0.05
  4838. # generate 2 2d grids for the x & y bounds
  4839. y, x = np.mgrid[slice(1, 5 + dy, dy),
  4840. slice(1, 5 + dx, dx)]
  4841. z = np.sin(x) ** 10 + np.cos(10 + y * x) * np.cos(x)
  4842. fig, ax = plt.subplots()
  4843. ax.pcolormesh(x, y, z)
  4844. ax.set_aspect(1.)
  4845. ax.apply_aspect()
  4846. # we need to apply_aspect to make the drawing below work.
  4847. xlim = [1.5, 2.15]
  4848. ylim = [2, 2.5]
  4849. rect = [xlim[0], ylim[0], xlim[1] - xlim[0], ylim[1] - ylim[0]]
  4850. rec, connectors = ax.indicate_inset(bounds=rect)
  4851. assert connectors is None
  4852. fig.canvas.draw()
  4853. xx = np.array([[1.5, 2.],
  4854. [2.15, 2.5]])
  4855. assert np.all(rec.get_bbox().get_points() == xx)
  4856. def test_zoom_inset():
  4857. dx, dy = 0.05, 0.05
  4858. # generate 2 2d grids for the x & y bounds
  4859. y, x = np.mgrid[slice(1, 5 + dy, dy),
  4860. slice(1, 5 + dx, dx)]
  4861. z = np.sin(x)**10 + np.cos(10 + y*x) * np.cos(x)
  4862. fig, ax = plt.subplots()
  4863. ax.pcolormesh(x, y, z)
  4864. ax.set_aspect(1.)
  4865. ax.apply_aspect()
  4866. # we need to apply_aspect to make the drawing below work.
  4867. # Make the inset_axes... Position axes co-ordinates...
  4868. axin1 = ax.inset_axes([0.7, 0.7, 0.35, 0.35])
  4869. # redraw the data in the inset axes...
  4870. axin1.pcolormesh(x, y, z)
  4871. axin1.set_xlim([1.5, 2.15])
  4872. axin1.set_ylim([2, 2.5])
  4873. axin1.set_aspect(ax.get_aspect())
  4874. rec, connectors = ax.indicate_inset_zoom(axin1)
  4875. assert len(connectors) == 4
  4876. fig.canvas.draw()
  4877. xx = np.array([[1.5, 2.],
  4878. [2.15, 2.5]])
  4879. assert(np.all(rec.get_bbox().get_points() == xx))
  4880. xx = np.array([[0.6325, 0.692308],
  4881. [0.8425, 0.907692]])
  4882. np.testing.assert_allclose(axin1.get_position().get_points(),
  4883. xx, rtol=1e-4)
  4884. @pytest.mark.parametrize('x_inverted', [False, True])
  4885. @pytest.mark.parametrize('y_inverted', [False, True])
  4886. def test_indicate_inset_inverted(x_inverted, y_inverted):
  4887. """
  4888. Test that the inset lines are correctly located with inverted data axes.
  4889. """
  4890. fig, (ax1, ax2) = plt.subplots(1, 2)
  4891. x = np.arange(10)
  4892. ax1.plot(x, x, 'o')
  4893. if x_inverted:
  4894. ax1.invert_xaxis()
  4895. if y_inverted:
  4896. ax1.invert_yaxis()
  4897. rect, bounds = ax1.indicate_inset([2, 2, 5, 4], ax2)
  4898. lower_left, upper_left, lower_right, upper_right = bounds
  4899. sign_x = -1 if x_inverted else 1
  4900. sign_y = -1 if y_inverted else 1
  4901. assert sign_x * (lower_right.xy2[0] - lower_left.xy2[0]) > 0
  4902. assert sign_x * (upper_right.xy2[0] - upper_left.xy2[0]) > 0
  4903. assert sign_y * (upper_left.xy2[1] - lower_left.xy2[1]) > 0
  4904. assert sign_y * (upper_right.xy2[1] - lower_right.xy2[1]) > 0
  4905. def test_set_position():
  4906. fig, ax = plt.subplots()
  4907. ax.set_aspect(3.)
  4908. ax.set_position([0.1, 0.1, 0.4, 0.4], which='both')
  4909. assert np.allclose(ax.get_position().width, 0.1)
  4910. ax.set_aspect(2.)
  4911. ax.set_position([0.1, 0.1, 0.4, 0.4], which='original')
  4912. assert np.allclose(ax.get_position().width, 0.15)
  4913. ax.set_aspect(3.)
  4914. ax.set_position([0.1, 0.1, 0.4, 0.4], which='active')
  4915. assert np.allclose(ax.get_position().width, 0.1)
  4916. def test_spines_properbbox_after_zoom():
  4917. fig, ax = plt.subplots()
  4918. bb = ax.spines['bottom'].get_window_extent(fig.canvas.get_renderer())
  4919. # this is what zoom calls:
  4920. ax._set_view_from_bbox((320, 320, 500, 500), 'in',
  4921. None, False, False)
  4922. bb2 = ax.spines['bottom'].get_window_extent(fig.canvas.get_renderer())
  4923. np.testing.assert_allclose(bb.get_points(), bb2.get_points(), rtol=1e-6)
  4924. def test_cartopy_backcompat():
  4925. import matplotlib
  4926. import matplotlib.axes
  4927. import matplotlib.axes._subplots
  4928. class Dummy(matplotlib.axes.Axes):
  4929. ...
  4930. class DummySubplot(matplotlib.axes.SubplotBase, Dummy):
  4931. _axes_class = Dummy
  4932. matplotlib.axes._subplots._subplot_classes[Dummy] = DummySubplot
  4933. FactoryDummySubplot = matplotlib.axes.subplot_class_factory(Dummy)
  4934. assert DummySubplot is FactoryDummySubplot
  4935. def test_gettightbbox_ignoreNaN():
  4936. fig, ax = plt.subplots()
  4937. remove_ticks_and_titles(fig)
  4938. ax.text(np.NaN, 1, 'Boo')
  4939. renderer = fig.canvas.get_renderer()
  4940. np.testing.assert_allclose(ax.get_tightbbox(renderer).width, 496)
  4941. def test_scatter_series_non_zero_index(pd):
  4942. # create non-zero index
  4943. ids = range(10, 18)
  4944. x = pd.Series(np.random.uniform(size=8), index=ids)
  4945. y = pd.Series(np.random.uniform(size=8), index=ids)
  4946. c = pd.Series([1, 1, 1, 1, 1, 0, 0, 0], index=ids)
  4947. plt.scatter(x, y, c)
  4948. def test_scatter_empty_data():
  4949. # making sure this does not raise an exception
  4950. plt.scatter([], [])
  4951. plt.scatter([], [], s=[], c=[])
  4952. @image_comparison(['annotate_across_transforms.png'],
  4953. style='mpl20', remove_text=True)
  4954. def test_annotate_across_transforms():
  4955. x = np.linspace(0, 10, 200)
  4956. y = np.exp(-x) * np.sin(x)
  4957. fig, ax = plt.subplots(figsize=(3.39, 3))
  4958. ax.plot(x, y)
  4959. axins = ax.inset_axes([0.4, 0.5, 0.3, 0.3])
  4960. axins.set_aspect(0.2)
  4961. axins.xaxis.set_visible(False)
  4962. axins.yaxis.set_visible(False)
  4963. ax.annotate("", xy=(x[150], y[150]), xycoords=ax.transData,
  4964. xytext=(1, 0), textcoords=axins.transAxes,
  4965. arrowprops=dict(arrowstyle="->"))
  4966. def test_deprecated_uppercase_colors():
  4967. # Remove after end of deprecation period.
  4968. fig, ax = plt.subplots()
  4969. with pytest.warns(MatplotlibDeprecationWarning):
  4970. ax.plot([1, 2], color="B")
  4971. fig.canvas.draw()
  4972. @image_comparison(['secondary_xy.png'], style='mpl20')
  4973. def test_secondary_xy():
  4974. fig, axs = plt.subplots(1, 2, figsize=(10, 5), constrained_layout=True)
  4975. def invert(x):
  4976. with np.errstate(divide='ignore'):
  4977. return 1 / x
  4978. for nn, ax in enumerate(axs):
  4979. ax.plot(np.arange(2, 11), np.arange(2, 11))
  4980. if nn == 0:
  4981. secax = ax.secondary_xaxis
  4982. else:
  4983. secax = ax.secondary_yaxis
  4984. secax(0.2, functions=(invert, invert))
  4985. secax(0.4, functions=(lambda x: 2 * x, lambda x: x / 2))
  4986. secax(0.6, functions=(lambda x: x**2, lambda x: x**(1/2)))
  4987. secax(0.8)
  4988. def test_secondary_fail():
  4989. fig, ax = plt.subplots()
  4990. ax.plot(np.arange(2, 11), np.arange(2, 11))
  4991. with pytest.raises(ValueError):
  4992. ax.secondary_xaxis(0.2, functions=(lambda x: 1 / x))
  4993. with pytest.raises(ValueError):
  4994. ax.secondary_xaxis('right')
  4995. with pytest.raises(ValueError):
  4996. ax.secondary_yaxis('bottom')
  4997. def test_secondary_resize():
  4998. fig, ax = plt.subplots(figsize=(10, 5))
  4999. ax.plot(np.arange(2, 11), np.arange(2, 11))
  5000. def invert(x):
  5001. with np.errstate(divide='ignore'):
  5002. return 1 / x
  5003. ax.secondary_xaxis('top', functions=(invert, invert))
  5004. fig.canvas.draw()
  5005. fig.set_size_inches((7, 4))
  5006. assert_allclose(ax.get_position().extents, [0.125, 0.1, 0.9, 0.9])
  5007. def test_secondary_minorloc():
  5008. fig, ax = plt.subplots(figsize=(10, 5))
  5009. ax.plot(np.arange(2, 11), np.arange(2, 11))
  5010. def invert(x):
  5011. with np.errstate(divide='ignore'):
  5012. return 1 / x
  5013. secax = ax.secondary_xaxis('top', functions=(invert, invert))
  5014. assert isinstance(secax._axis.get_minor_locator(),
  5015. mticker.NullLocator)
  5016. secax.minorticks_on()
  5017. assert isinstance(secax._axis.get_minor_locator(),
  5018. mticker.AutoMinorLocator)
  5019. ax.set_xscale('log')
  5020. plt.draw()
  5021. assert isinstance(secax._axis.get_minor_locator(),
  5022. mticker.LogLocator)
  5023. ax.set_xscale('linear')
  5024. plt.draw()
  5025. assert isinstance(secax._axis.get_minor_locator(),
  5026. mticker.NullLocator)
  5027. def color_boxes(fig, axs):
  5028. """
  5029. Helper for the tests below that test the extents of various axes elements
  5030. """
  5031. fig.canvas.draw()
  5032. renderer = fig.canvas.get_renderer()
  5033. bbaxis = []
  5034. for nn, axx in enumerate([axs.xaxis, axs.yaxis]):
  5035. bb = axx.get_tightbbox(renderer)
  5036. if bb:
  5037. axisr = plt.Rectangle((bb.x0, bb.y0), width=bb.width,
  5038. height=bb.height, linewidth=0.7, edgecolor='y',
  5039. facecolor="none", transform=None, zorder=3)
  5040. fig.add_artist(axisr)
  5041. bbaxis += [bb]
  5042. bbspines = []
  5043. for nn, a in enumerate(['bottom', 'top', 'left', 'right']):
  5044. bb = axs.spines[a].get_window_extent(renderer)
  5045. spiner = plt.Rectangle((bb.x0, bb.y0), width=bb.width,
  5046. height=bb.height, linewidth=0.7,
  5047. edgecolor="green", facecolor="none",
  5048. transform=None, zorder=3)
  5049. fig.add_artist(spiner)
  5050. bbspines += [bb]
  5051. bb = axs.get_window_extent()
  5052. rect2 = plt.Rectangle((bb.x0, bb.y0), width=bb.width, height=bb.height,
  5053. linewidth=1.5, edgecolor="magenta",
  5054. facecolor="none", transform=None, zorder=2)
  5055. fig.add_artist(rect2)
  5056. bbax = bb
  5057. bb2 = axs.get_tightbbox(renderer)
  5058. rect2 = plt.Rectangle((bb2.x0, bb2.y0), width=bb2.width,
  5059. height=bb2.height, linewidth=3, edgecolor="red",
  5060. facecolor="none", transform=None, zorder=1)
  5061. fig.add_artist(rect2)
  5062. bbtb = bb2
  5063. return bbaxis, bbspines, bbax, bbtb
  5064. def test_normal_axes():
  5065. with rc_context({'_internal.classic_mode': False}):
  5066. fig, ax = plt.subplots(dpi=200, figsize=(6, 6))
  5067. fig.canvas.draw()
  5068. plt.close(fig)
  5069. bbaxis, bbspines, bbax, bbtb = color_boxes(fig, ax)
  5070. # test the axis bboxes
  5071. target = [
  5072. [123.375, 75.88888888888886, 983.25, 33.0],
  5073. [85.51388888888889, 99.99999999999997, 53.375, 993.0]
  5074. ]
  5075. for nn, b in enumerate(bbaxis):
  5076. targetbb = mtransforms.Bbox.from_bounds(*target[nn])
  5077. assert_array_almost_equal(b.bounds, targetbb.bounds, decimal=2)
  5078. target = [
  5079. [150.0, 119.999, 930.0, 11.111],
  5080. [150.0, 1080.0, 930.0, 0.0],
  5081. [150.0, 119.9999, 11.111, 960.0],
  5082. [1068.8888, 119.9999, 11.111, 960.0]
  5083. ]
  5084. for nn, b in enumerate(bbspines):
  5085. targetbb = mtransforms.Bbox.from_bounds(*target[nn])
  5086. assert_array_almost_equal(b.bounds, targetbb.bounds, decimal=2)
  5087. target = [150.0, 119.99999999999997, 930.0, 960.0]
  5088. targetbb = mtransforms.Bbox.from_bounds(*target)
  5089. assert_array_almost_equal(bbax.bounds, targetbb.bounds, decimal=2)
  5090. target = [85.5138, 75.88888, 1021.11, 1017.11]
  5091. targetbb = mtransforms.Bbox.from_bounds(*target)
  5092. assert_array_almost_equal(bbtb.bounds, targetbb.bounds, decimal=2)
  5093. # test that get_position roundtrips to get_window_extent
  5094. axbb = ax.get_position().transformed(fig.transFigure).bounds
  5095. assert_array_almost_equal(axbb, ax.get_window_extent().bounds, decimal=2)
  5096. def test_nodecorator():
  5097. with rc_context({'_internal.classic_mode': False}):
  5098. fig, ax = plt.subplots(dpi=200, figsize=(6, 6))
  5099. fig.canvas.draw()
  5100. ax.set(xticklabels=[], yticklabels=[])
  5101. bbaxis, bbspines, bbax, bbtb = color_boxes(fig, ax)
  5102. # test the axis bboxes
  5103. target = [
  5104. None,
  5105. None
  5106. ]
  5107. for nn, b in enumerate(bbaxis):
  5108. assert b is None
  5109. target = [
  5110. [150.0, 119.999, 930.0, 11.111],
  5111. [150.0, 1080.0, 930.0, 0.0],
  5112. [150.0, 119.9999, 11.111, 960.0],
  5113. [1068.8888, 119.9999, 11.111, 960.0]
  5114. ]
  5115. for nn, b in enumerate(bbspines):
  5116. targetbb = mtransforms.Bbox.from_bounds(*target[nn])
  5117. assert_allclose(b.bounds, targetbb.bounds, atol=1e-2)
  5118. target = [150.0, 119.99999999999997, 930.0, 960.0]
  5119. targetbb = mtransforms.Bbox.from_bounds(*target)
  5120. assert_allclose(bbax.bounds, targetbb.bounds, atol=1e-2)
  5121. target = [150., 120., 930., 960.]
  5122. targetbb = mtransforms.Bbox.from_bounds(*target)
  5123. assert_allclose(bbtb.bounds, targetbb.bounds, atol=1e-2)
  5124. def test_displaced_spine():
  5125. with rc_context({'_internal.classic_mode': False}):
  5126. fig, ax = plt.subplots(dpi=200, figsize=(6, 6))
  5127. ax.set(xticklabels=[], yticklabels=[])
  5128. ax.spines['bottom'].set_position(('axes', -0.1))
  5129. fig.canvas.draw()
  5130. bbaxis, bbspines, bbax, bbtb = color_boxes(fig, ax)
  5131. target = [
  5132. [150., 24., 930., 11.111111],
  5133. [150.0, 1080.0, 930.0, 0.0],
  5134. [150.0, 119.9999, 11.111, 960.0],
  5135. [1068.8888, 119.9999, 11.111, 960.0]
  5136. ]
  5137. for nn, b in enumerate(bbspines):
  5138. targetbb = mtransforms.Bbox.from_bounds(*target[nn])
  5139. target = [150.0, 119.99999999999997, 930.0, 960.0]
  5140. targetbb = mtransforms.Bbox.from_bounds(*target)
  5141. assert_allclose(bbax.bounds, targetbb.bounds, atol=1e-2)
  5142. target = [150., 24., 930., 1056.]
  5143. targetbb = mtransforms.Bbox.from_bounds(*target)
  5144. assert_allclose(bbtb.bounds, targetbb.bounds, atol=1e-2)
  5145. def test_tickdirs():
  5146. """
  5147. Switch the tickdirs and make sure the bboxes switch with them
  5148. """
  5149. targets = [[[150.0, 120.0, 930.0, 11.1111],
  5150. [150.0, 120.0, 11.111, 960.0]],
  5151. [[150.0, 108.8889, 930.0, 11.111111111111114],
  5152. [138.889, 120, 11.111, 960.0]],
  5153. [[150.0, 114.44444444444441, 930.0, 11.111111111111114],
  5154. [144.44444444444446, 119.999, 11.111, 960.0]]]
  5155. for dnum, dirs in enumerate(['in', 'out', 'inout']):
  5156. with rc_context({'_internal.classic_mode': False}):
  5157. fig, ax = plt.subplots(dpi=200, figsize=(6, 6))
  5158. ax.tick_params(direction=dirs)
  5159. fig.canvas.draw()
  5160. bbaxis, bbspines, bbax, bbtb = color_boxes(fig, ax)
  5161. for nn, num in enumerate([0, 2]):
  5162. targetbb = mtransforms.Bbox.from_bounds(*targets[dnum][nn])
  5163. assert_allclose(bbspines[num].bounds, targetbb.bounds,
  5164. atol=1e-2)
  5165. def test_minor_accountedfor():
  5166. with rc_context({'_internal.classic_mode': False}):
  5167. fig, ax = plt.subplots(dpi=200, figsize=(6, 6))
  5168. fig.canvas.draw()
  5169. ax.tick_params(which='both', direction='out')
  5170. bbaxis, bbspines, bbax, bbtb = color_boxes(fig, ax)
  5171. bbaxis, bbspines, bbax, bbtb = color_boxes(fig, ax)
  5172. targets = [[150.0, 108.88888888888886, 930.0, 11.111111111111114],
  5173. [138.8889, 119.9999, 11.1111, 960.0]]
  5174. for n in range(2):
  5175. targetbb = mtransforms.Bbox.from_bounds(*targets[n])
  5176. assert_allclose(bbspines[n * 2].bounds, targetbb.bounds,
  5177. atol=1e-2)
  5178. fig, ax = plt.subplots(dpi=200, figsize=(6, 6))
  5179. fig.canvas.draw()
  5180. ax.tick_params(which='both', direction='out')
  5181. ax.minorticks_on()
  5182. ax.tick_params(axis='both', which='minor', length=30)
  5183. fig.canvas.draw()
  5184. bbaxis, bbspines, bbax, bbtb = color_boxes(fig, ax)
  5185. targets = [[150.0, 36.66666666666663, 930.0, 83.33333333333334],
  5186. [66.6667, 120.0, 83.3333, 960.0]]
  5187. for n in range(2):
  5188. targetbb = mtransforms.Bbox.from_bounds(*targets[n])
  5189. assert_allclose(bbspines[n * 2].bounds, targetbb.bounds,
  5190. atol=1e-2)
  5191. def test_get_tightbbox_polar():
  5192. fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
  5193. fig.canvas.draw()
  5194. bb = ax.get_tightbbox(fig.canvas.get_renderer())
  5195. assert_allclose(bb.extents,
  5196. [107.7778, 29.2778, 539.7847, 450.7222], rtol=1e-03)
  5197. @check_figures_equal(extensions=["png"])
  5198. def test_axis_bool_arguments(fig_test, fig_ref):
  5199. # Test if False and "off" give the same
  5200. fig_test.add_subplot(211).axis(False)
  5201. fig_ref.add_subplot(211).axis("off")
  5202. # Test if True after False gives the same as "on"
  5203. ax = fig_test.add_subplot(212)
  5204. ax.axis(False)
  5205. ax.axis(True)
  5206. fig_ref.add_subplot(212).axis("on")
  5207. def test_axis_extent_arg():
  5208. fig, ax = plt.subplots()
  5209. xmin = 5
  5210. xmax = 10
  5211. ymin = 15
  5212. ymax = 20
  5213. extent = ax.axis([xmin, xmax, ymin, ymax])
  5214. # test that the docstring is correct
  5215. assert tuple(extent) == (xmin, xmax, ymin, ymax)
  5216. # test that limits were set per the docstring
  5217. assert (xmin, xmax) == ax.get_xlim()
  5218. assert (ymin, ymax) == ax.get_ylim()
  5219. def test_datetime_masked():
  5220. # make sure that all-masked data falls back to the viewlim
  5221. # set in convert.axisinfo....
  5222. x = np.array([datetime.datetime(2017, 1, n) for n in range(1, 6)])
  5223. y = np.array([1, 2, 3, 4, 5])
  5224. m = np.ma.masked_greater(y, 0)
  5225. fig, ax = plt.subplots()
  5226. ax.plot(x, m)
  5227. # these are the default viewlim
  5228. assert ax.get_xlim() == (730120.0, 733773.0)
  5229. def test_hist_auto_bins():
  5230. _, bins, _ = plt.hist([[1, 2, 3], [3, 4, 5, 6]], bins='auto')
  5231. assert bins[0] <= 1
  5232. assert bins[-1] >= 6
  5233. def test_hist_nan_data():
  5234. fig, (ax1, ax2) = plt.subplots(2)
  5235. data = [1, 2, 3]
  5236. nan_data = data + [np.nan]
  5237. bins, edges, _ = ax1.hist(data)
  5238. with np.errstate(invalid='ignore'):
  5239. nanbins, nanedges, _ = ax2.hist(nan_data)
  5240. np.testing.assert_allclose(bins, nanbins)
  5241. np.testing.assert_allclose(edges, nanedges)
  5242. def test_hist_range_and_density():
  5243. _, bins, _ = plt.hist(np.random.rand(10), "auto",
  5244. range=(0, 1), density=True)
  5245. assert bins[0] == 0
  5246. assert bins[-1] == 1
  5247. def test_bar_errbar_zorder():
  5248. # Check that the zorder of errorbars is always greater than the bar they
  5249. # are plotted on
  5250. fig, ax = plt.subplots()
  5251. x = [1, 2, 3]
  5252. barcont = ax.bar(x=x, height=x, yerr=x, capsize=5, zorder=3)
  5253. data_line, caplines, barlinecols = barcont.errorbar.lines
  5254. for bar in barcont.patches:
  5255. for capline in caplines:
  5256. assert capline.zorder > bar.zorder
  5257. for barlinecol in barlinecols:
  5258. assert barlinecol.zorder > bar.zorder
  5259. def test_set_ticks_inverted():
  5260. fig, ax = plt.subplots()
  5261. ax.invert_xaxis()
  5262. ax.set_xticks([.3, .7])
  5263. assert ax.get_xlim() == (1, 0)
  5264. def test_aspect_nonlinear_adjustable_box():
  5265. fig = plt.figure(figsize=(10, 10)) # Square.
  5266. ax = fig.add_subplot()
  5267. ax.plot([.4, .6], [.4, .6]) # Set minpos to keep logit happy.
  5268. ax.set(xscale="log", xlim=(1, 10),
  5269. yscale="logit", ylim=(1/11, 1/1001),
  5270. aspect=1, adjustable="box")
  5271. ax.margins(0)
  5272. pos = fig.transFigure.transform_bbox(ax.get_position())
  5273. assert pos.height / pos.width == pytest.approx(2)
  5274. def test_aspect_nonlinear_adjustable_datalim():
  5275. fig = plt.figure(figsize=(10, 10)) # Square.
  5276. ax = fig.add_axes([.1, .1, .8, .8]) # Square.
  5277. ax.plot([.4, .6], [.4, .6]) # Set minpos to keep logit happy.
  5278. ax.set(xscale="log", xlim=(1, 100),
  5279. yscale="logit", ylim=(1 / 101, 1 / 11),
  5280. aspect=1, adjustable="datalim")
  5281. ax.margins(0)
  5282. ax.apply_aspect()
  5283. assert ax.get_xlim() == pytest.approx([1*10**(1/2), 100/10**(1/2)])
  5284. assert ax.get_ylim() == (1 / 101, 1 / 11)
  5285. def test_invisible_axes():
  5286. # invisible axes should not respond to events...
  5287. fig, ax = plt.subplots()
  5288. assert fig.canvas.inaxes((200, 200)) is not None
  5289. ax.set_visible(False)
  5290. assert fig.canvas.inaxes((200, 200)) is None