_axes.py 305 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098
  1. import collections.abc
  2. import functools
  3. import itertools
  4. import logging
  5. import math
  6. from numbers import Number
  7. import numpy as np
  8. from numpy import ma
  9. import matplotlib.category as _ # <-registers a category unit converter
  10. import matplotlib.cbook as cbook
  11. import matplotlib.collections as mcoll
  12. import matplotlib.colors as mcolors
  13. import matplotlib.contour as mcontour
  14. import matplotlib.dates as _ # <-registers a date unit converter
  15. import matplotlib.docstring as docstring
  16. import matplotlib.image as mimage
  17. import matplotlib.legend as mlegend
  18. import matplotlib.lines as mlines
  19. import matplotlib.markers as mmarkers
  20. import matplotlib.mlab as mlab
  21. import matplotlib.patches as mpatches
  22. import matplotlib.path as mpath
  23. import matplotlib.quiver as mquiver
  24. import matplotlib.stackplot as mstack
  25. import matplotlib.streamplot as mstream
  26. import matplotlib.table as mtable
  27. import matplotlib.text as mtext
  28. import matplotlib.ticker as mticker
  29. import matplotlib.transforms as mtransforms
  30. import matplotlib.tri as mtri
  31. from matplotlib import _preprocess_data, rcParams
  32. from matplotlib.axes._base import _AxesBase, _process_plot_format
  33. from matplotlib.axes._secondary_axes import SecondaryAxis
  34. from matplotlib.container import BarContainer, ErrorbarContainer, StemContainer
  35. try:
  36. from numpy.lib.histograms import (
  37. histogram_bin_edges as _histogram_bin_edges)
  38. except ImportError:
  39. # this function is new in np 1.15
  40. def _histogram_bin_edges(arr, bins, range=None, weights=None):
  41. # this in True for 1D arrays, and False for None and str
  42. if np.ndim(bins) == 1:
  43. return bins
  44. if isinstance(bins, str):
  45. # rather than backporting the internals, just do the full
  46. # computation. If this is too slow for users, they can
  47. # update numpy, or pick a manual number of bins
  48. return np.histogram(arr, bins, range, weights)[1]
  49. else:
  50. if bins is None:
  51. # hard-code numpy's default
  52. bins = 10
  53. if range is None:
  54. range = np.min(arr), np.max(arr)
  55. return np.linspace(*range, bins + 1)
  56. _log = logging.getLogger(__name__)
  57. def _make_inset_locator(bounds, trans, parent):
  58. """
  59. Helper function to locate inset axes, used in
  60. `.Axes.inset_axes`.
  61. A locator gets used in `Axes.set_aspect` to override the default
  62. locations... It is a function that takes an axes object and
  63. a renderer and tells `set_aspect` where it is to be placed.
  64. Here *rect* is a rectangle [l, b, w, h] that specifies the
  65. location for the axes in the transform given by *trans* on the
  66. *parent*.
  67. """
  68. _bounds = mtransforms.Bbox.from_bounds(*bounds)
  69. _trans = trans
  70. _parent = parent
  71. def inset_locator(ax, renderer):
  72. bbox = _bounds
  73. bb = mtransforms.TransformedBbox(bbox, _trans)
  74. tr = _parent.figure.transFigure.inverted()
  75. bb = mtransforms.TransformedBbox(bb, tr)
  76. return bb
  77. return inset_locator
  78. # The axes module contains all the wrappers to plotting functions.
  79. # All the other methods should go in the _AxesBase class.
  80. class Axes(_AxesBase):
  81. """
  82. The `Axes` contains most of the figure elements: `~.axis.Axis`,
  83. `~.axis.Tick`, `~.lines.Line2D`, `~.text.Text`, `~.patches.Polygon`, etc.,
  84. and sets the coordinate system.
  85. The `Axes` instance supports callbacks through a callbacks attribute which
  86. is a `~.cbook.CallbackRegistry` instance. The events you can connect to
  87. are 'xlim_changed' and 'ylim_changed' and the callback will be called with
  88. func(*ax*) where *ax* is the `Axes` instance.
  89. Attributes
  90. ----------
  91. dataLim : `.Bbox`
  92. The bounding box enclosing all data displayed in the Axes.
  93. viewLim : `.Bbox`
  94. The view limits in data coordinates.
  95. """
  96. ### Labelling, legend and texts
  97. @cbook.deprecated("3.1")
  98. @property
  99. def aname(self):
  100. return 'Axes'
  101. def get_title(self, loc="center"):
  102. """
  103. Get an axes title.
  104. Get one of the three available axes titles. The available titles
  105. are positioned above the axes in the center, flush with the left
  106. edge, and flush with the right edge.
  107. Parameters
  108. ----------
  109. loc : {'center', 'left', 'right'}, str, optional
  110. Which title to get, defaults to 'center'.
  111. Returns
  112. -------
  113. title : str
  114. The title text string.
  115. """
  116. titles = {'left': self._left_title,
  117. 'center': self.title,
  118. 'right': self._right_title}
  119. title = cbook._check_getitem(titles, loc=loc.lower())
  120. return title.get_text()
  121. def set_title(self, label, fontdict=None, loc=None, pad=None,
  122. **kwargs):
  123. """
  124. Set a title for the axes.
  125. Set one of the three available axes titles. The available titles
  126. are positioned above the axes in the center, flush with the left
  127. edge, and flush with the right edge.
  128. Parameters
  129. ----------
  130. label : str
  131. Text to use for the title
  132. fontdict : dict
  133. A dictionary controlling the appearance of the title text,
  134. the default *fontdict* is::
  135. {'fontsize': rcParams['axes.titlesize'],
  136. 'fontweight' : rcParams['axes.titleweight'],
  137. 'color' : rcParams['axes.titlecolor'],
  138. 'verticalalignment': 'baseline',
  139. 'horizontalalignment': loc}
  140. loc : {'center', 'left', 'right'}, str, optional
  141. Which title to set.
  142. If *None*, defaults to :rc:`axes.titlelocation`.
  143. pad : float
  144. The offset of the title from the top of the axes, in points.
  145. If *None*, defaults to :rc:`axes.titlepad`.
  146. Returns
  147. -------
  148. text : :class:`~matplotlib.text.Text`
  149. The matplotlib text instance representing the title
  150. Other Parameters
  151. ----------------
  152. **kwargs : `~matplotlib.text.Text` properties
  153. Other keyword arguments are text properties, see
  154. :class:`~matplotlib.text.Text` for a list of valid text
  155. properties.
  156. """
  157. if loc is None:
  158. loc = rcParams['axes.titlelocation']
  159. titles = {'left': self._left_title,
  160. 'center': self.title,
  161. 'right': self._right_title}
  162. title = cbook._check_getitem(titles, loc=loc.lower())
  163. default = {
  164. 'fontsize': rcParams['axes.titlesize'],
  165. 'fontweight': rcParams['axes.titleweight'],
  166. 'verticalalignment': 'baseline',
  167. 'horizontalalignment': loc.lower()}
  168. titlecolor = rcParams['axes.titlecolor']
  169. if not cbook._str_lower_equal(titlecolor, 'auto'):
  170. default["color"] = titlecolor
  171. if pad is None:
  172. pad = rcParams['axes.titlepad']
  173. self._set_title_offset_trans(float(pad))
  174. title.set_text(label)
  175. title.update(default)
  176. if fontdict is not None:
  177. title.update(fontdict)
  178. title.update(kwargs)
  179. return title
  180. def get_xlabel(self):
  181. """
  182. Get the xlabel text string.
  183. """
  184. label = self.xaxis.get_label()
  185. return label.get_text()
  186. def set_xlabel(self, xlabel, fontdict=None, labelpad=None, **kwargs):
  187. """
  188. Set the label for the x-axis.
  189. Parameters
  190. ----------
  191. xlabel : str
  192. The label text.
  193. labelpad : scalar, optional, default: None
  194. Spacing in points from the axes bounding box including ticks
  195. and tick labels.
  196. Other Parameters
  197. ----------------
  198. **kwargs : `.Text` properties
  199. `.Text` properties control the appearance of the label.
  200. See also
  201. --------
  202. text : for information on how override and the optional args work
  203. """
  204. if labelpad is not None:
  205. self.xaxis.labelpad = labelpad
  206. return self.xaxis.set_label_text(xlabel, fontdict, **kwargs)
  207. def get_ylabel(self):
  208. """
  209. Get the ylabel text string.
  210. """
  211. label = self.yaxis.get_label()
  212. return label.get_text()
  213. def set_ylabel(self, ylabel, fontdict=None, labelpad=None, **kwargs):
  214. """
  215. Set the label for the y-axis.
  216. Parameters
  217. ----------
  218. ylabel : str
  219. The label text.
  220. labelpad : scalar, optional, default: None
  221. Spacing in points from the axes bounding box including ticks
  222. and tick labels.
  223. Other Parameters
  224. ----------------
  225. **kwargs : `.Text` properties
  226. `.Text` properties control the appearance of the label.
  227. See also
  228. --------
  229. text : for information on how override and the optional args work
  230. """
  231. if labelpad is not None:
  232. self.yaxis.labelpad = labelpad
  233. return self.yaxis.set_label_text(ylabel, fontdict, **kwargs)
  234. def get_legend_handles_labels(self, legend_handler_map=None):
  235. """
  236. Return handles and labels for legend
  237. ``ax.legend()`` is equivalent to ::
  238. h, l = ax.get_legend_handles_labels()
  239. ax.legend(h, l)
  240. """
  241. # pass through to legend.
  242. handles, labels = mlegend._get_legend_handles_labels([self],
  243. legend_handler_map)
  244. return handles, labels
  245. @docstring.dedent_interpd
  246. def legend(self, *args, **kwargs):
  247. """
  248. Place a legend on the axes.
  249. Call signatures::
  250. legend()
  251. legend(labels)
  252. legend(handles, labels)
  253. The call signatures correspond to three different ways how to use
  254. this method.
  255. **1. Automatic detection of elements to be shown in the legend**
  256. The elements to be added to the legend are automatically determined,
  257. when you do not pass in any extra arguments.
  258. In this case, the labels are taken from the artist. You can specify
  259. them either at artist creation or by calling the
  260. :meth:`~.Artist.set_label` method on the artist::
  261. line, = ax.plot([1, 2, 3], label='Inline label')
  262. ax.legend()
  263. or::
  264. line, = ax.plot([1, 2, 3])
  265. line.set_label('Label via method')
  266. ax.legend()
  267. Specific lines can be excluded from the automatic legend element
  268. selection by defining a label starting with an underscore.
  269. This is default for all artists, so calling `Axes.legend` without
  270. any arguments and without setting the labels manually will result in
  271. no legend being drawn.
  272. **2. Labeling existing plot elements**
  273. To make a legend for lines which already exist on the axes
  274. (via plot for instance), simply call this function with an iterable
  275. of strings, one for each legend item. For example::
  276. ax.plot([1, 2, 3])
  277. ax.legend(['A simple line'])
  278. Note: This way of using is discouraged, because the relation between
  279. plot elements and labels is only implicit by their order and can
  280. easily be mixed up.
  281. **3. Explicitly defining the elements in the legend**
  282. For full control of which artists have a legend entry, it is possible
  283. to pass an iterable of legend artists followed by an iterable of
  284. legend labels respectively::
  285. legend((line1, line2, line3), ('label1', 'label2', 'label3'))
  286. Parameters
  287. ----------
  288. handles : sequence of `.Artist`, optional
  289. A list of Artists (lines, patches) to be added to the legend.
  290. Use this together with *labels*, if you need full control on what
  291. is shown in the legend and the automatic mechanism described above
  292. is not sufficient.
  293. The length of handles and labels should be the same in this
  294. case. If they are not, they are truncated to the smaller length.
  295. labels : list of str, optional
  296. A list of labels to show next to the artists.
  297. Use this together with *handles*, if you need full control on what
  298. is shown in the legend and the automatic mechanism described above
  299. is not sufficient.
  300. Other Parameters
  301. ----------------
  302. %(_legend_kw_doc)s
  303. Returns
  304. -------
  305. legend : `~matplotlib.legend.Legend`
  306. Notes
  307. -----
  308. Not all kinds of artist are supported by the legend command. See
  309. :doc:`/tutorials/intermediate/legend_guide` for details.
  310. Examples
  311. --------
  312. .. plot:: gallery/text_labels_and_annotations/legend.py
  313. """
  314. handles, labels, extra_args, kwargs = mlegend._parse_legend_args(
  315. [self],
  316. *args,
  317. **kwargs)
  318. if len(extra_args):
  319. raise TypeError('legend only accepts two non-keyword arguments')
  320. self.legend_ = mlegend.Legend(self, handles, labels, **kwargs)
  321. self.legend_._remove_method = self._remove_legend
  322. return self.legend_
  323. def _remove_legend(self, legend):
  324. self.legend_ = None
  325. def inset_axes(self, bounds, *, transform=None, zorder=5,
  326. **kwargs):
  327. """
  328. Add a child inset axes to this existing axes.
  329. Warnings
  330. --------
  331. This method is experimental as of 3.0, and the API may change.
  332. Parameters
  333. ----------
  334. bounds : [x0, y0, width, height]
  335. Lower-left corner of inset axes, and its width and height.
  336. transform : `.Transform`
  337. Defaults to `ax.transAxes`, i.e. the units of *rect* are in
  338. axes-relative coordinates.
  339. zorder : number
  340. Defaults to 5 (same as `.Axes.legend`). Adjust higher or lower
  341. to change whether it is above or below data plotted on the
  342. parent axes.
  343. **kwargs
  344. Other keyword arguments are passed on to the `.Axes` child axes.
  345. Returns
  346. -------
  347. ax
  348. The created `~.axes.Axes` instance.
  349. Examples
  350. --------
  351. This example makes two inset axes, the first is in axes-relative
  352. coordinates, and the second in data-coordinates::
  353. fig, ax = plt.subplots()
  354. ax.plot(range(10))
  355. axin1 = ax.inset_axes([0.8, 0.1, 0.15, 0.15])
  356. axin2 = ax.inset_axes(
  357. [5, 7, 2.3, 2.3], transform=ax.transData)
  358. """
  359. if transform is None:
  360. transform = self.transAxes
  361. label = kwargs.pop('label', 'inset_axes')
  362. # This puts the rectangle into figure-relative coordinates.
  363. inset_locator = _make_inset_locator(bounds, transform, self)
  364. bb = inset_locator(None, None)
  365. inset_ax = Axes(self.figure, bb.bounds, zorder=zorder,
  366. label=label, **kwargs)
  367. # this locator lets the axes move if in data coordinates.
  368. # it gets called in `ax.apply_aspect() (of all places)
  369. inset_ax.set_axes_locator(inset_locator)
  370. self.add_child_axes(inset_ax)
  371. return inset_ax
  372. def indicate_inset(self, bounds, inset_ax=None, *, transform=None,
  373. facecolor='none', edgecolor='0.5', alpha=0.5,
  374. zorder=4.99, **kwargs):
  375. """
  376. Add an inset indicator to the axes. This is a rectangle on the plot
  377. at the position indicated by *bounds* that optionally has lines that
  378. connect the rectangle to an inset axes (`.Axes.inset_axes`).
  379. Warnings
  380. --------
  381. This method is experimental as of 3.0, and the API may change.
  382. Parameters
  383. ----------
  384. bounds : [x0, y0, width, height]
  385. Lower-left corner of rectangle to be marked, and its width
  386. and height.
  387. inset_ax : `.Axes`
  388. An optional inset axes to draw connecting lines to. Two lines are
  389. drawn connecting the indicator box to the inset axes on corners
  390. chosen so as to not overlap with the indicator box.
  391. transform : `.Transform`
  392. Transform for the rectangle co-ordinates. Defaults to
  393. `ax.transAxes`, i.e. the units of *rect* are in axes-relative
  394. coordinates.
  395. facecolor : Matplotlib color
  396. Facecolor of the rectangle (default 'none').
  397. edgecolor : Matplotlib color
  398. Color of the rectangle and color of the connecting lines. Default
  399. is '0.5'.
  400. alpha : float
  401. Transparency of the rectangle and connector lines. Default is 0.5.
  402. zorder : float
  403. Drawing order of the rectangle and connector lines. Default is 4.99
  404. (just below the default level of inset axes).
  405. **kwargs
  406. Other keyword arguments are passed on to the rectangle patch.
  407. Returns
  408. -------
  409. rectangle_patch : `.patches.Rectangle`
  410. The indicator frame.
  411. connector_lines : 4-tuple of `.patches.ConnectionPatch`
  412. The four connector lines connecting to (lower_left, upper_left,
  413. lower_right upper_right) corners of *inset_ax*. Two lines are
  414. set with visibility to *False*, but the user can set the
  415. visibility to True if the automatic choice is not deemed correct.
  416. """
  417. # to make the axes connectors work, we need to apply the aspect to
  418. # the parent axes.
  419. self.apply_aspect()
  420. if transform is None:
  421. transform = self.transData
  422. label = kwargs.pop('label', 'indicate_inset')
  423. x, y, width, height = bounds
  424. rectangle_patch = mpatches.Rectangle(
  425. (x, y), width, height,
  426. facecolor=facecolor, edgecolor=edgecolor, alpha=alpha,
  427. zorder=zorder, label=label, transform=transform, **kwargs)
  428. self.add_patch(rectangle_patch)
  429. connects = []
  430. if inset_ax is not None:
  431. # connect the inset_axes to the rectangle
  432. for xy_inset_ax in [(0, 0), (0, 1), (1, 0), (1, 1)]:
  433. # inset_ax positions are in axes coordinates
  434. # The 0, 1 values define the four edges if the inset_ax
  435. # lower_left, upper_left, lower_right upper_right.
  436. ex, ey = xy_inset_ax
  437. if self.xaxis.get_inverted():
  438. ex = 1 - ex
  439. if self.yaxis.get_inverted():
  440. ey = 1 - ey
  441. xy_data = x + ex * width, y + ey * height
  442. p = mpatches.ConnectionPatch(
  443. xyA=xy_inset_ax, coordsA=inset_ax.transAxes,
  444. xyB=xy_data, coordsB=self.transData,
  445. arrowstyle="-", zorder=zorder,
  446. edgecolor=edgecolor, alpha=alpha)
  447. connects.append(p)
  448. self.add_patch(p)
  449. # decide which two of the lines to keep visible....
  450. pos = inset_ax.get_position()
  451. bboxins = pos.transformed(self.figure.transFigure)
  452. rectbbox = mtransforms.Bbox.from_bounds(
  453. *bounds
  454. ).transformed(transform)
  455. x0 = rectbbox.x0 < bboxins.x0
  456. x1 = rectbbox.x1 < bboxins.x1
  457. y0 = rectbbox.y0 < bboxins.y0
  458. y1 = rectbbox.y1 < bboxins.y1
  459. connects[0].set_visible(x0 ^ y0)
  460. connects[1].set_visible(x0 == y1)
  461. connects[2].set_visible(x1 == y0)
  462. connects[3].set_visible(x1 ^ y1)
  463. return rectangle_patch, tuple(connects) if connects else None
  464. def indicate_inset_zoom(self, inset_ax, **kwargs):
  465. """
  466. Add an inset indicator rectangle to the axes based on the axis
  467. limits for an *inset_ax* and draw connectors between *inset_ax*
  468. and the rectangle.
  469. Warnings
  470. --------
  471. This method is experimental as of 3.0, and the API may change.
  472. Parameters
  473. ----------
  474. inset_ax : `.Axes`
  475. Inset axes to draw connecting lines to. Two lines are
  476. drawn connecting the indicator box to the inset axes on corners
  477. chosen so as to not overlap with the indicator box.
  478. **kwargs
  479. Other keyword arguments are passed on to `.Axes.indicate_inset`
  480. Returns
  481. -------
  482. rectangle_patch : `.Patches.Rectangle`
  483. Rectangle artist.
  484. connector_lines : 4-tuple of `.Patches.ConnectionPatch`
  485. Each of four connector lines coming from the rectangle drawn on
  486. this axis, in the order lower left, upper left, lower right,
  487. upper right.
  488. Two are set with visibility to *False*, but the user can
  489. set the visibility to *True* if the automatic choice is not deemed
  490. correct.
  491. """
  492. xlim = inset_ax.get_xlim()
  493. ylim = inset_ax.get_ylim()
  494. rect = (xlim[0], ylim[0], xlim[1] - xlim[0], ylim[1] - ylim[0])
  495. return self.indicate_inset(rect, inset_ax, **kwargs)
  496. @docstring.dedent_interpd
  497. def secondary_xaxis(self, location, *, functions=None, **kwargs):
  498. """
  499. Add a second x-axis to this axes.
  500. For example if we want to have a second scale for the data plotted on
  501. the xaxis.
  502. %(_secax_docstring)s
  503. Examples
  504. --------
  505. The main axis shows frequency, and the secondary axis shows period.
  506. .. plot::
  507. fig, ax = plt.subplots()
  508. ax.loglog(range(1, 360, 5), range(1, 360, 5))
  509. ax.set_xlabel('frequency [Hz]')
  510. def invert(x):
  511. return 1 / x
  512. secax = ax.secondary_xaxis('top', functions=(invert, invert))
  513. secax.set_xlabel('Period [s]')
  514. plt.show()
  515. """
  516. if (location in ['top', 'bottom'] or isinstance(location, Number)):
  517. secondary_ax = SecondaryAxis(self, 'x', location, functions,
  518. **kwargs)
  519. self.add_child_axes(secondary_ax)
  520. return secondary_ax
  521. else:
  522. raise ValueError('secondary_xaxis location must be either '
  523. 'a float or "top"/"bottom"')
  524. def secondary_yaxis(self, location, *, functions=None, **kwargs):
  525. """
  526. Add a second y-axis to this axes.
  527. For example if we want to have a second scale for the data plotted on
  528. the yaxis.
  529. %(_secax_docstring)s
  530. Examples
  531. --------
  532. Add a secondary axes that converts from radians to degrees
  533. .. plot::
  534. fig, ax = plt.subplots()
  535. ax.plot(range(1, 360, 5), range(1, 360, 5))
  536. ax.set_ylabel('degrees')
  537. secax = ax.secondary_yaxis('right', functions=(np.deg2rad,
  538. np.rad2deg))
  539. secax.set_ylabel('radians')
  540. """
  541. if location in ['left', 'right'] or isinstance(location, Number):
  542. secondary_ax = SecondaryAxis(self, 'y', location,
  543. functions, **kwargs)
  544. self.add_child_axes(secondary_ax)
  545. return secondary_ax
  546. else:
  547. raise ValueError('secondary_yaxis location must be either '
  548. 'a float or "left"/"right"')
  549. @cbook._delete_parameter("3.1", "withdash")
  550. def text(self, x, y, s, fontdict=None, withdash=False, **kwargs):
  551. """
  552. Add text to the axes.
  553. Add the text *s* to the axes at location *x*, *y* in data coordinates.
  554. Parameters
  555. ----------
  556. x, y : scalars
  557. The position to place the text. By default, this is in data
  558. coordinates. The coordinate system can be changed using the
  559. *transform* parameter.
  560. s : str
  561. The text.
  562. fontdict : dictionary, optional, default: None
  563. A dictionary to override the default text properties. If fontdict
  564. is None, the defaults are determined by your rc parameters.
  565. withdash : boolean, optional, default: False
  566. Creates a `~matplotlib.text.TextWithDash` instance instead of a
  567. `~matplotlib.text.Text` instance.
  568. Returns
  569. -------
  570. text : `.Text`
  571. The created `.Text` instance.
  572. Other Parameters
  573. ----------------
  574. **kwargs : `~matplotlib.text.Text` properties.
  575. Other miscellaneous text parameters.
  576. Examples
  577. --------
  578. Individual keyword arguments can be used to override any given
  579. parameter::
  580. >>> text(x, y, s, fontsize=12)
  581. The default transform specifies that text is in data coords,
  582. alternatively, you can specify text in axis coords ((0, 0) is
  583. lower-left and (1, 1) is upper-right). The example below places
  584. text in the center of the axes::
  585. >>> text(0.5, 0.5, 'matplotlib', horizontalalignment='center',
  586. ... verticalalignment='center', transform=ax.transAxes)
  587. You can put a rectangular box around the text instance (e.g., to
  588. set a background color) by using the keyword *bbox*. *bbox* is
  589. a dictionary of `~matplotlib.patches.Rectangle`
  590. properties. For example::
  591. >>> text(x, y, s, bbox=dict(facecolor='red', alpha=0.5))
  592. """
  593. if fontdict is None:
  594. fontdict = {}
  595. effective_kwargs = {
  596. 'verticalalignment': 'baseline',
  597. 'horizontalalignment': 'left',
  598. 'transform': self.transData,
  599. 'clip_on': False,
  600. **fontdict,
  601. **kwargs,
  602. }
  603. # At some point if we feel confident that TextWithDash
  604. # is robust as a drop-in replacement for Text and that
  605. # the performance impact of the heavier-weight class
  606. # isn't too significant, it may make sense to eliminate
  607. # the withdash kwarg and simply delegate whether there's
  608. # a dash to TextWithDash and dashlength.
  609. if (withdash
  610. and withdash is not cbook.deprecation._deprecated_parameter):
  611. t = mtext.TextWithDash(x, y, text=s)
  612. else:
  613. t = mtext.Text(x, y, text=s)
  614. t.update(effective_kwargs)
  615. t.set_clip_path(self.patch)
  616. self._add_text(t)
  617. return t
  618. @docstring.dedent_interpd
  619. def annotate(self, s, xy, *args, **kwargs):
  620. a = mtext.Annotation(s, xy, *args, **kwargs)
  621. a.set_transform(mtransforms.IdentityTransform())
  622. if 'clip_on' in kwargs:
  623. a.set_clip_path(self.patch)
  624. self._add_text(a)
  625. return a
  626. annotate.__doc__ = mtext.Annotation.__init__.__doc__
  627. #### Lines and spans
  628. @docstring.dedent_interpd
  629. def axhline(self, y=0, xmin=0, xmax=1, **kwargs):
  630. """
  631. Add a horizontal line across the axis.
  632. Parameters
  633. ----------
  634. y : scalar, optional, default: 0
  635. y position in data coordinates of the horizontal line.
  636. xmin : scalar, optional, default: 0
  637. Should be between 0 and 1, 0 being the far left of the plot, 1 the
  638. far right of the plot.
  639. xmax : scalar, optional, default: 1
  640. Should be between 0 and 1, 0 being the far left of the plot, 1 the
  641. far right of the plot.
  642. Returns
  643. -------
  644. line : `~matplotlib.lines.Line2D`
  645. Other Parameters
  646. ----------------
  647. **kwargs
  648. Valid keyword arguments are `.Line2D` properties, with the
  649. exception of 'transform':
  650. %(_Line2D_docstr)s
  651. See also
  652. --------
  653. hlines : Add horizontal lines in data coordinates.
  654. axhspan : Add a horizontal span (rectangle) across the axis.
  655. Examples
  656. --------
  657. * draw a thick red hline at 'y' = 0 that spans the xrange::
  658. >>> axhline(linewidth=4, color='r')
  659. * draw a default hline at 'y' = 1 that spans the xrange::
  660. >>> axhline(y=1)
  661. * draw a default hline at 'y' = .5 that spans the middle half of
  662. the xrange::
  663. >>> axhline(y=.5, xmin=0.25, xmax=0.75)
  664. """
  665. if "transform" in kwargs:
  666. raise ValueError(
  667. "'transform' is not allowed as a kwarg;"
  668. + "axhline generates its own transform.")
  669. ymin, ymax = self.get_ybound()
  670. # We need to strip away the units for comparison with
  671. # non-unitized bounds
  672. self._process_unit_info(ydata=y, kwargs=kwargs)
  673. yy = self.convert_yunits(y)
  674. scaley = (yy < ymin) or (yy > ymax)
  675. trans = self.get_yaxis_transform(which='grid')
  676. l = mlines.Line2D([xmin, xmax], [y, y], transform=trans, **kwargs)
  677. self.add_line(l)
  678. self._request_autoscale_view(scalex=False, scaley=scaley)
  679. return l
  680. @docstring.dedent_interpd
  681. def axvline(self, x=0, ymin=0, ymax=1, **kwargs):
  682. """
  683. Add a vertical line across the axes.
  684. Parameters
  685. ----------
  686. x : scalar, optional, default: 0
  687. x position in data coordinates of the vertical line.
  688. ymin : scalar, optional, default: 0
  689. Should be between 0 and 1, 0 being the bottom of the plot, 1 the
  690. top of the plot.
  691. ymax : scalar, optional, default: 1
  692. Should be between 0 and 1, 0 being the bottom of the plot, 1 the
  693. top of the plot.
  694. Returns
  695. -------
  696. line : `~matplotlib.lines.Line2D`
  697. Other Parameters
  698. ----------------
  699. **kwargs
  700. Valid keyword arguments are `.Line2D` properties, with the
  701. exception of 'transform':
  702. %(_Line2D_docstr)s
  703. Examples
  704. --------
  705. * draw a thick red vline at *x* = 0 that spans the yrange::
  706. >>> axvline(linewidth=4, color='r')
  707. * draw a default vline at *x* = 1 that spans the yrange::
  708. >>> axvline(x=1)
  709. * draw a default vline at *x* = .5 that spans the middle half of
  710. the yrange::
  711. >>> axvline(x=.5, ymin=0.25, ymax=0.75)
  712. See also
  713. --------
  714. vlines : Add vertical lines in data coordinates.
  715. axvspan : Add a vertical span (rectangle) across the axis.
  716. """
  717. if "transform" in kwargs:
  718. raise ValueError(
  719. "'transform' is not allowed as a kwarg;"
  720. + "axvline generates its own transform.")
  721. xmin, xmax = self.get_xbound()
  722. # We need to strip away the units for comparison with
  723. # non-unitized bounds
  724. self._process_unit_info(xdata=x, kwargs=kwargs)
  725. xx = self.convert_xunits(x)
  726. scalex = (xx < xmin) or (xx > xmax)
  727. trans = self.get_xaxis_transform(which='grid')
  728. l = mlines.Line2D([x, x], [ymin, ymax], transform=trans, **kwargs)
  729. self.add_line(l)
  730. self._request_autoscale_view(scalex=scalex, scaley=False)
  731. return l
  732. @docstring.dedent_interpd
  733. def axhspan(self, ymin, ymax, xmin=0, xmax=1, **kwargs):
  734. """
  735. Add a horizontal span (rectangle) across the axis.
  736. Draw a horizontal span (rectangle) from *ymin* to *ymax*.
  737. With the default values of *xmin* = 0 and *xmax* = 1, this
  738. always spans the xrange, regardless of the xlim settings, even
  739. if you change them, e.g., with the :meth:`set_xlim` command.
  740. That is, the horizontal extent is in axes coords: 0=left,
  741. 0.5=middle, 1.0=right but the *y* location is in data
  742. coordinates.
  743. Parameters
  744. ----------
  745. ymin : float
  746. Lower limit of the horizontal span in data units.
  747. ymax : float
  748. Upper limit of the horizontal span in data units.
  749. xmin : float, optional, default: 0
  750. Lower limit of the vertical span in axes (relative
  751. 0-1) units.
  752. xmax : float, optional, default: 1
  753. Upper limit of the vertical span in axes (relative
  754. 0-1) units.
  755. Returns
  756. -------
  757. Polygon : `~matplotlib.patches.Polygon`
  758. Other Parameters
  759. ----------------
  760. **kwargs : `~matplotlib.patches.Polygon` properties.
  761. %(Polygon)s
  762. See Also
  763. --------
  764. axvspan : Add a vertical span across the axes.
  765. """
  766. trans = self.get_yaxis_transform(which='grid')
  767. # process the unit information
  768. self._process_unit_info([xmin, xmax], [ymin, ymax], kwargs=kwargs)
  769. # first we need to strip away the units
  770. xmin, xmax = self.convert_xunits([xmin, xmax])
  771. ymin, ymax = self.convert_yunits([ymin, ymax])
  772. verts = (xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)
  773. p = mpatches.Polygon(verts, **kwargs)
  774. p.set_transform(trans)
  775. self.add_patch(p)
  776. self._request_autoscale_view(scalex=False)
  777. return p
  778. def axvspan(self, xmin, xmax, ymin=0, ymax=1, **kwargs):
  779. """
  780. Add a vertical span (rectangle) across the axes.
  781. Draw a vertical span (rectangle) from *xmin* to *xmax*. With
  782. the default values of *ymin* = 0 and *ymax* = 1. This always
  783. spans the yrange, regardless of the ylim settings, even if you
  784. change them, e.g., with the :meth:`set_ylim` command. That is,
  785. the vertical extent is in axes coords: 0=bottom, 0.5=middle,
  786. 1.0=top but the x location is in data coordinates.
  787. Parameters
  788. ----------
  789. xmin : scalar
  790. Number indicating the first X-axis coordinate of the vertical
  791. span rectangle in data units.
  792. xmax : scalar
  793. Number indicating the second X-axis coordinate of the vertical
  794. span rectangle in data units.
  795. ymin : scalar, optional
  796. Number indicating the first Y-axis coordinate of the vertical
  797. span rectangle in relative Y-axis units (0-1). Default to 0.
  798. ymax : scalar, optional
  799. Number indicating the second Y-axis coordinate of the vertical
  800. span rectangle in relative Y-axis units (0-1). Default to 1.
  801. Returns
  802. -------
  803. rectangle : `~matplotlib.patches.Polygon`
  804. Vertical span (rectangle) from (xmin, ymin) to (xmax, ymax).
  805. Other Parameters
  806. ----------------
  807. **kwargs
  808. Optional parameters are properties of the class `.Polygon`.
  809. See Also
  810. --------
  811. axhspan : Add a horizontal span across the axes.
  812. Examples
  813. --------
  814. Draw a vertical, green, translucent rectangle from x = 1.25 to
  815. x = 1.55 that spans the yrange of the axes.
  816. >>> axvspan(1.25, 1.55, facecolor='g', alpha=0.5)
  817. """
  818. trans = self.get_xaxis_transform(which='grid')
  819. # process the unit information
  820. self._process_unit_info([xmin, xmax], [ymin, ymax], kwargs=kwargs)
  821. # first we need to strip away the units
  822. xmin, xmax = self.convert_xunits([xmin, xmax])
  823. ymin, ymax = self.convert_yunits([ymin, ymax])
  824. verts = [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)]
  825. p = mpatches.Polygon(verts, **kwargs)
  826. p.set_transform(trans)
  827. self.add_patch(p)
  828. self._request_autoscale_view(scaley=False)
  829. return p
  830. @_preprocess_data(replace_names=["y", "xmin", "xmax", "colors"],
  831. label_namer="y")
  832. def hlines(self, y, xmin, xmax, colors='k', linestyles='solid',
  833. label='', **kwargs):
  834. """
  835. Plot horizontal lines at each *y* from *xmin* to *xmax*.
  836. Parameters
  837. ----------
  838. y : scalar or sequence of scalar
  839. y-indexes where to plot the lines.
  840. xmin, xmax : scalar or 1D array-like
  841. Respective beginning and end of each line. If scalars are
  842. provided, all lines will have same length.
  843. colors : array-like of colors, optional, default: 'k'
  844. linestyles : {'solid', 'dashed', 'dashdot', 'dotted'}, optional
  845. label : str, optional, default: ''
  846. Returns
  847. -------
  848. lines : `~matplotlib.collections.LineCollection`
  849. Other Parameters
  850. ----------------
  851. **kwargs : `~matplotlib.collections.LineCollection` properties.
  852. See also
  853. --------
  854. vlines : vertical lines
  855. axhline: horizontal line across the axes
  856. """
  857. # We do the conversion first since not all unitized data is uniform
  858. # process the unit information
  859. self._process_unit_info([xmin, xmax], y, kwargs=kwargs)
  860. y = self.convert_yunits(y)
  861. xmin = self.convert_xunits(xmin)
  862. xmax = self.convert_xunits(xmax)
  863. if not np.iterable(y):
  864. y = [y]
  865. if not np.iterable(xmin):
  866. xmin = [xmin]
  867. if not np.iterable(xmax):
  868. xmax = [xmax]
  869. y, xmin, xmax = cbook.delete_masked_points(y, xmin, xmax)
  870. y = np.ravel(y)
  871. xmin = np.resize(xmin, y.shape)
  872. xmax = np.resize(xmax, y.shape)
  873. verts = [((thisxmin, thisy), (thisxmax, thisy))
  874. for thisxmin, thisxmax, thisy in zip(xmin, xmax, y)]
  875. lines = mcoll.LineCollection(verts, colors=colors,
  876. linestyles=linestyles, label=label)
  877. self.add_collection(lines, autolim=False)
  878. lines.update(kwargs)
  879. if len(y) > 0:
  880. minx = min(xmin.min(), xmax.min())
  881. maxx = max(xmin.max(), xmax.max())
  882. miny = y.min()
  883. maxy = y.max()
  884. corners = (minx, miny), (maxx, maxy)
  885. self.update_datalim(corners)
  886. self._request_autoscale_view()
  887. return lines
  888. @_preprocess_data(replace_names=["x", "ymin", "ymax", "colors"],
  889. label_namer="x")
  890. def vlines(self, x, ymin, ymax, colors='k', linestyles='solid',
  891. label='', **kwargs):
  892. """
  893. Plot vertical lines.
  894. Plot vertical lines at each *x* from *ymin* to *ymax*.
  895. Parameters
  896. ----------
  897. x : scalar or 1D array-like
  898. x-indexes where to plot the lines.
  899. ymin, ymax : scalar or 1D array-like
  900. Respective beginning and end of each line. If scalars are
  901. provided, all lines will have same length.
  902. colors : array-like of colors, optional, default: 'k'
  903. linestyles : {'solid', 'dashed', 'dashdot', 'dotted'}, optional
  904. label : str, optional, default: ''
  905. Returns
  906. -------
  907. lines : `~matplotlib.collections.LineCollection`
  908. Other Parameters
  909. ----------------
  910. **kwargs : `~matplotlib.collections.LineCollection` properties.
  911. See also
  912. --------
  913. hlines : horizontal lines
  914. axvline: vertical line across the axes
  915. """
  916. self._process_unit_info(xdata=x, ydata=[ymin, ymax], kwargs=kwargs)
  917. # We do the conversion first since not all unitized data is uniform
  918. x = self.convert_xunits(x)
  919. ymin = self.convert_yunits(ymin)
  920. ymax = self.convert_yunits(ymax)
  921. if not np.iterable(x):
  922. x = [x]
  923. if not np.iterable(ymin):
  924. ymin = [ymin]
  925. if not np.iterable(ymax):
  926. ymax = [ymax]
  927. x, ymin, ymax = cbook.delete_masked_points(x, ymin, ymax)
  928. x = np.ravel(x)
  929. ymin = np.resize(ymin, x.shape)
  930. ymax = np.resize(ymax, x.shape)
  931. verts = [((thisx, thisymin), (thisx, thisymax))
  932. for thisx, thisymin, thisymax in zip(x, ymin, ymax)]
  933. lines = mcoll.LineCollection(verts, colors=colors,
  934. linestyles=linestyles, label=label)
  935. self.add_collection(lines, autolim=False)
  936. lines.update(kwargs)
  937. if len(x) > 0:
  938. minx = x.min()
  939. maxx = x.max()
  940. miny = min(ymin.min(), ymax.min())
  941. maxy = max(ymin.max(), ymax.max())
  942. corners = (minx, miny), (maxx, maxy)
  943. self.update_datalim(corners)
  944. self._request_autoscale_view()
  945. return lines
  946. @_preprocess_data(replace_names=["positions", "lineoffsets",
  947. "linelengths", "linewidths",
  948. "colors", "linestyles"])
  949. @docstring.dedent_interpd
  950. def eventplot(self, positions, orientation='horizontal', lineoffsets=1,
  951. linelengths=1, linewidths=None, colors=None,
  952. linestyles='solid', **kwargs):
  953. """
  954. Plot identical parallel lines at the given positions.
  955. *positions* should be a 1D or 2D array-like object, with each row
  956. corresponding to a row or column of lines.
  957. This type of plot is commonly used in neuroscience for representing
  958. neural events, where it is usually called a spike raster, dot raster,
  959. or raster plot.
  960. However, it is useful in any situation where you wish to show the
  961. timing or position of multiple sets of discrete events, such as the
  962. arrival times of people to a business on each day of the month or the
  963. date of hurricanes each year of the last century.
  964. Parameters
  965. ----------
  966. positions : 1D or 2D array-like object
  967. Each value is an event. If *positions* is a 2D array-like, each
  968. row corresponds to a row or a column of lines (depending on the
  969. *orientation* parameter).
  970. orientation : {'horizontal', 'vertical'}, optional
  971. Controls the direction of the event collections:
  972. - 'horizontal' : the lines are arranged horizontally in rows,
  973. and are vertical.
  974. - 'vertical' : the lines are arranged vertically in columns,
  975. and are horizontal.
  976. lineoffsets : scalar or sequence of scalars, optional, default: 1
  977. The offset of the center of the lines from the origin, in the
  978. direction orthogonal to *orientation*.
  979. linelengths : scalar or sequence of scalars, optional, default: 1
  980. The total height of the lines (i.e. the lines stretches from
  981. ``lineoffset - linelength/2`` to ``lineoffset + linelength/2``).
  982. linewidths : scalar, scalar sequence or None, optional, default: None
  983. The line width(s) of the event lines, in points. If it is None,
  984. defaults to its rcParams setting.
  985. colors : color, sequence of colors or None, optional, default: None
  986. The color(s) of the event lines. If it is None, defaults to its
  987. rcParams setting.
  988. linestyles : str or tuple or a sequence of such values, optional
  989. Default is 'solid'. Valid strings are ['solid', 'dashed',
  990. 'dashdot', 'dotted', '-', '--', '-.', ':']. Dash tuples
  991. should be of the form::
  992. (offset, onoffseq),
  993. where *onoffseq* is an even length tuple of on and off ink
  994. in points.
  995. **kwargs : optional
  996. Other keyword arguments are line collection properties. See
  997. :class:`~matplotlib.collections.LineCollection` for a list of
  998. the valid properties.
  999. Returns
  1000. -------
  1001. list : A list of :class:`~.collections.EventCollection` objects.
  1002. Contains the :class:`~.collections.EventCollection` that
  1003. were added.
  1004. Notes
  1005. -----
  1006. For *linelengths*, *linewidths*, *colors*, and *linestyles*, if only
  1007. a single value is given, that value is applied to all lines. If an
  1008. array-like is given, it must have the same length as *positions*, and
  1009. each value will be applied to the corresponding row of the array.
  1010. Examples
  1011. --------
  1012. .. plot:: gallery/lines_bars_and_markers/eventplot_demo.py
  1013. """
  1014. self._process_unit_info(xdata=positions,
  1015. ydata=[lineoffsets, linelengths],
  1016. kwargs=kwargs)
  1017. # We do the conversion first since not all unitized data is uniform
  1018. positions = self.convert_xunits(positions)
  1019. lineoffsets = self.convert_yunits(lineoffsets)
  1020. linelengths = self.convert_yunits(linelengths)
  1021. if not np.iterable(positions):
  1022. positions = [positions]
  1023. elif any(np.iterable(position) for position in positions):
  1024. positions = [np.asanyarray(position) for position in positions]
  1025. else:
  1026. positions = [np.asanyarray(positions)]
  1027. if len(positions) == 0:
  1028. return []
  1029. # prevent 'singular' keys from **kwargs dict from overriding the effect
  1030. # of 'plural' keyword arguments (e.g. 'color' overriding 'colors')
  1031. colors = cbook.local_over_kwdict(colors, kwargs, 'color')
  1032. linewidths = cbook.local_over_kwdict(linewidths, kwargs, 'linewidth')
  1033. linestyles = cbook.local_over_kwdict(linestyles, kwargs, 'linestyle')
  1034. if not np.iterable(lineoffsets):
  1035. lineoffsets = [lineoffsets]
  1036. if not np.iterable(linelengths):
  1037. linelengths = [linelengths]
  1038. if not np.iterable(linewidths):
  1039. linewidths = [linewidths]
  1040. if not np.iterable(colors):
  1041. colors = [colors]
  1042. if hasattr(linestyles, 'lower') or not np.iterable(linestyles):
  1043. linestyles = [linestyles]
  1044. lineoffsets = np.asarray(lineoffsets)
  1045. linelengths = np.asarray(linelengths)
  1046. linewidths = np.asarray(linewidths)
  1047. if len(lineoffsets) == 0:
  1048. lineoffsets = [None]
  1049. if len(linelengths) == 0:
  1050. linelengths = [None]
  1051. if len(linewidths) == 0:
  1052. lineoffsets = [None]
  1053. if len(linewidths) == 0:
  1054. lineoffsets = [None]
  1055. if len(colors) == 0:
  1056. colors = [None]
  1057. try:
  1058. # Early conversion of the colors into RGBA values to take care
  1059. # of cases like colors='0.5' or colors='C1'. (Issue #8193)
  1060. colors = mcolors.to_rgba_array(colors)
  1061. except ValueError:
  1062. # Will fail if any element of *colors* is None. But as long
  1063. # as len(colors) == 1 or len(positions), the rest of the
  1064. # code should process *colors* properly.
  1065. pass
  1066. if len(lineoffsets) == 1 and len(positions) != 1:
  1067. lineoffsets = np.tile(lineoffsets, len(positions))
  1068. lineoffsets[0] = 0
  1069. lineoffsets = np.cumsum(lineoffsets)
  1070. if len(linelengths) == 1:
  1071. linelengths = np.tile(linelengths, len(positions))
  1072. if len(linewidths) == 1:
  1073. linewidths = np.tile(linewidths, len(positions))
  1074. if len(colors) == 1:
  1075. colors = list(colors)
  1076. colors = colors * len(positions)
  1077. if len(linestyles) == 1:
  1078. linestyles = [linestyles] * len(positions)
  1079. if len(lineoffsets) != len(positions):
  1080. raise ValueError('lineoffsets and positions are unequal sized '
  1081. 'sequences')
  1082. if len(linelengths) != len(positions):
  1083. raise ValueError('linelengths and positions are unequal sized '
  1084. 'sequences')
  1085. if len(linewidths) != len(positions):
  1086. raise ValueError('linewidths and positions are unequal sized '
  1087. 'sequences')
  1088. if len(colors) != len(positions):
  1089. raise ValueError('colors and positions are unequal sized '
  1090. 'sequences')
  1091. if len(linestyles) != len(positions):
  1092. raise ValueError('linestyles and positions are unequal sized '
  1093. 'sequences')
  1094. colls = []
  1095. for position, lineoffset, linelength, linewidth, color, linestyle in \
  1096. zip(positions, lineoffsets, linelengths, linewidths,
  1097. colors, linestyles):
  1098. coll = mcoll.EventCollection(position,
  1099. orientation=orientation,
  1100. lineoffset=lineoffset,
  1101. linelength=linelength,
  1102. linewidth=linewidth,
  1103. color=color,
  1104. linestyle=linestyle)
  1105. self.add_collection(coll, autolim=False)
  1106. coll.update(kwargs)
  1107. colls.append(coll)
  1108. if len(positions) > 0:
  1109. # try to get min/max
  1110. min_max = [(np.min(_p), np.max(_p)) for _p in positions
  1111. if len(_p) > 0]
  1112. # if we have any non-empty positions, try to autoscale
  1113. if len(min_max) > 0:
  1114. mins, maxes = zip(*min_max)
  1115. minpos = np.min(mins)
  1116. maxpos = np.max(maxes)
  1117. minline = (lineoffsets - linelengths).min()
  1118. maxline = (lineoffsets + linelengths).max()
  1119. if (orientation is not None and
  1120. orientation.lower() == "vertical"):
  1121. corners = (minline, minpos), (maxline, maxpos)
  1122. else: # "horizontal", None or "none" (see EventCollection)
  1123. corners = (minpos, minline), (maxpos, maxline)
  1124. self.update_datalim(corners)
  1125. self._request_autoscale_view()
  1126. return colls
  1127. #### Basic plotting
  1128. # Uses a custom implementation of data-kwarg handling in
  1129. # _process_plot_var_args.
  1130. @docstring.dedent_interpd
  1131. def plot(self, *args, scalex=True, scaley=True, data=None, **kwargs):
  1132. """
  1133. Plot y versus x as lines and/or markers.
  1134. Call signatures::
  1135. plot([x], y, [fmt], *, data=None, **kwargs)
  1136. plot([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)
  1137. The coordinates of the points or line nodes are given by *x*, *y*.
  1138. The optional parameter *fmt* is a convenient way for defining basic
  1139. formatting like color, marker and linestyle. It's a shortcut string
  1140. notation described in the *Notes* section below.
  1141. >>> plot(x, y) # plot x and y using default line style and color
  1142. >>> plot(x, y, 'bo') # plot x and y using blue circle markers
  1143. >>> plot(y) # plot y using x as index array 0..N-1
  1144. >>> plot(y, 'r+') # ditto, but with red plusses
  1145. You can use `.Line2D` properties as keyword arguments for more
  1146. control on the appearance. Line properties and *fmt* can be mixed.
  1147. The following two calls yield identical results:
  1148. >>> plot(x, y, 'go--', linewidth=2, markersize=12)
  1149. >>> plot(x, y, color='green', marker='o', linestyle='dashed',
  1150. ... linewidth=2, markersize=12)
  1151. When conflicting with *fmt*, keyword arguments take precedence.
  1152. **Plotting labelled data**
  1153. There's a convenient way for plotting objects with labelled data (i.e.
  1154. data that can be accessed by index ``obj['y']``). Instead of giving
  1155. the data in *x* and *y*, you can provide the object in the *data*
  1156. parameter and just give the labels for *x* and *y*::
  1157. >>> plot('xlabel', 'ylabel', data=obj)
  1158. All indexable objects are supported. This could e.g. be a `dict`, a
  1159. `pandas.DataFame` or a structured numpy array.
  1160. **Plotting multiple sets of data**
  1161. There are various ways to plot multiple sets of data.
  1162. - The most straight forward way is just to call `plot` multiple times.
  1163. Example:
  1164. >>> plot(x1, y1, 'bo')
  1165. >>> plot(x2, y2, 'go')
  1166. - Alternatively, if your data is already a 2d array, you can pass it
  1167. directly to *x*, *y*. A separate data set will be drawn for every
  1168. column.
  1169. Example: an array ``a`` where the first column represents the *x*
  1170. values and the other columns are the *y* columns::
  1171. >>> plot(a[0], a[1:])
  1172. - The third way is to specify multiple sets of *[x]*, *y*, *[fmt]*
  1173. groups::
  1174. >>> plot(x1, y1, 'g^', x2, y2, 'g-')
  1175. In this case, any additional keyword argument applies to all
  1176. datasets. Also this syntax cannot be combined with the *data*
  1177. parameter.
  1178. By default, each line is assigned a different style specified by a
  1179. 'style cycle'. The *fmt* and line property parameters are only
  1180. necessary if you want explicit deviations from these defaults.
  1181. Alternatively, you can also change the style cycle using
  1182. :rc:`axes.prop_cycle`.
  1183. Parameters
  1184. ----------
  1185. x, y : array-like or scalar
  1186. The horizontal / vertical coordinates of the data points.
  1187. *x* values are optional and default to `range(len(y))`.
  1188. Commonly, these parameters are 1D arrays.
  1189. They can also be scalars, or two-dimensional (in that case, the
  1190. columns represent separate data sets).
  1191. These arguments cannot be passed as keywords.
  1192. fmt : str, optional
  1193. A format string, e.g. 'ro' for red circles. See the *Notes*
  1194. section for a full description of the format strings.
  1195. Format strings are just an abbreviation for quickly setting
  1196. basic line properties. All of these and more can also be
  1197. controlled by keyword arguments.
  1198. This argument cannot be passed as keyword.
  1199. data : indexable object, optional
  1200. An object with labelled data. If given, provide the label names to
  1201. plot in *x* and *y*.
  1202. .. note::
  1203. Technically there's a slight ambiguity in calls where the
  1204. second label is a valid *fmt*. `plot('n', 'o', data=obj)`
  1205. could be `plt(x, y)` or `plt(y, fmt)`. In such cases,
  1206. the former interpretation is chosen, but a warning is issued.
  1207. You may suppress the warning by adding an empty format string
  1208. `plot('n', 'o', '', data=obj)`.
  1209. Other Parameters
  1210. ----------------
  1211. scalex, scaley : bool, optional, default: True
  1212. These parameters determined if the view limits are adapted to
  1213. the data limits. The values are passed on to `autoscale_view`.
  1214. **kwargs : `.Line2D` properties, optional
  1215. *kwargs* are used to specify properties like a line label (for
  1216. auto legends), linewidth, antialiasing, marker face color.
  1217. Example::
  1218. >>> plot([1, 2, 3], [1, 2, 3], 'go-', label='line 1', linewidth=2)
  1219. >>> plot([1, 2, 3], [1, 4, 9], 'rs', label='line 2')
  1220. If you make multiple lines with one plot command, the kwargs
  1221. apply to all those lines.
  1222. Here is a list of available `.Line2D` properties:
  1223. %(_Line2D_docstr)s
  1224. Returns
  1225. -------
  1226. lines
  1227. A list of `.Line2D` objects representing the plotted data.
  1228. See Also
  1229. --------
  1230. scatter : XY scatter plot with markers of varying size and/or color (
  1231. sometimes also called bubble chart).
  1232. Notes
  1233. -----
  1234. **Format Strings**
  1235. A format string consists of a part for color, marker and line::
  1236. fmt = '[marker][line][color]'
  1237. Each of them is optional. If not provided, the value from the style
  1238. cycle is used. Exception: If ``line`` is given, but no ``marker``,
  1239. the data will be a line without markers.
  1240. Other combinations such as ``[color][marker][line]`` are also
  1241. supported, but note that their parsing may be ambiguous.
  1242. **Markers**
  1243. ============= ===============================
  1244. character description
  1245. ============= ===============================
  1246. ``'.'`` point marker
  1247. ``','`` pixel marker
  1248. ``'o'`` circle marker
  1249. ``'v'`` triangle_down marker
  1250. ``'^'`` triangle_up marker
  1251. ``'<'`` triangle_left marker
  1252. ``'>'`` triangle_right marker
  1253. ``'1'`` tri_down marker
  1254. ``'2'`` tri_up marker
  1255. ``'3'`` tri_left marker
  1256. ``'4'`` tri_right marker
  1257. ``'s'`` square marker
  1258. ``'p'`` pentagon marker
  1259. ``'*'`` star marker
  1260. ``'h'`` hexagon1 marker
  1261. ``'H'`` hexagon2 marker
  1262. ``'+'`` plus marker
  1263. ``'x'`` x marker
  1264. ``'D'`` diamond marker
  1265. ``'d'`` thin_diamond marker
  1266. ``'|'`` vline marker
  1267. ``'_'`` hline marker
  1268. ============= ===============================
  1269. **Line Styles**
  1270. ============= ===============================
  1271. character description
  1272. ============= ===============================
  1273. ``'-'`` solid line style
  1274. ``'--'`` dashed line style
  1275. ``'-.'`` dash-dot line style
  1276. ``':'`` dotted line style
  1277. ============= ===============================
  1278. Example format strings::
  1279. 'b' # blue markers with default shape
  1280. 'or' # red circles
  1281. '-g' # green solid line
  1282. '--' # dashed line with default color
  1283. '^k:' # black triangle_up markers connected by a dotted line
  1284. **Colors**
  1285. The supported color abbreviations are the single letter codes
  1286. ============= ===============================
  1287. character color
  1288. ============= ===============================
  1289. ``'b'`` blue
  1290. ``'g'`` green
  1291. ``'r'`` red
  1292. ``'c'`` cyan
  1293. ``'m'`` magenta
  1294. ``'y'`` yellow
  1295. ``'k'`` black
  1296. ``'w'`` white
  1297. ============= ===============================
  1298. and the ``'CN'`` colors that index into the default property cycle.
  1299. If the color is the only part of the format string, you can
  1300. additionally use any `matplotlib.colors` spec, e.g. full names
  1301. (``'green'``) or hex strings (``'#008000'``).
  1302. """
  1303. kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)
  1304. lines = [*self._get_lines(*args, data=data, **kwargs)]
  1305. for line in lines:
  1306. self.add_line(line)
  1307. self._request_autoscale_view(scalex=scalex, scaley=scaley)
  1308. return lines
  1309. @_preprocess_data(replace_names=["x", "y"], label_namer="y")
  1310. @docstring.dedent_interpd
  1311. def plot_date(self, x, y, fmt='o', tz=None, xdate=True, ydate=False,
  1312. **kwargs):
  1313. """
  1314. Plot data that contains dates.
  1315. Similar to `.plot`, this plots *y* vs. *x* as lines or markers.
  1316. However, the axis labels are formatted as dates depending on *xdate*
  1317. and *ydate*.
  1318. Parameters
  1319. ----------
  1320. x, y : array-like
  1321. The coordinates of the data points. If *xdate* or *ydate* is
  1322. *True*, the respective values *x* or *y* are interpreted as
  1323. :ref:`Matplotlib dates <date-format>`.
  1324. fmt : str, optional
  1325. The plot format string. For details, see the corresponding
  1326. parameter in `.plot`.
  1327. tz : timezone string or `tzinfo` or None
  1328. The time zone to use in labeling dates. If *None*, defaults to
  1329. :rc:`timezone`.
  1330. xdate : bool, optional, default: True
  1331. If *True*, the *x*-axis will be interpreted as Matplotlib dates.
  1332. ydate : bool, optional, default: False
  1333. If *True*, the *y*-axis will be interpreted as Matplotlib dates.
  1334. Returns
  1335. -------
  1336. lines
  1337. A list of `.Line2D` objects representing the plotted data.
  1338. Other Parameters
  1339. ----------------
  1340. **kwargs
  1341. Keyword arguments control the `.Line2D` properties:
  1342. %(_Line2D_docstr)s
  1343. See Also
  1344. --------
  1345. matplotlib.dates : Helper functions on dates.
  1346. matplotlib.dates.date2num : Convert dates to num.
  1347. matplotlib.dates.num2date : Convert num to dates.
  1348. matplotlib.dates.drange : Create an equally spaced sequence of dates.
  1349. Notes
  1350. -----
  1351. If you are using custom date tickers and formatters, it may be
  1352. necessary to set the formatters/locators after the call to
  1353. `.plot_date`. `.plot_date` will set the default tick locator to
  1354. `.AutoDateLocator` (if the tick locator is not already set to a
  1355. `.DateLocator` instance) and the default tick formatter to
  1356. `.AutoDateFormatter` (if the tick formatter is not already set to a
  1357. `.DateFormatter` instance).
  1358. """
  1359. if xdate:
  1360. self.xaxis_date(tz)
  1361. if ydate:
  1362. self.yaxis_date(tz)
  1363. ret = self.plot(x, y, fmt, **kwargs)
  1364. self._request_autoscale_view()
  1365. return ret
  1366. # @_preprocess_data() # let 'plot' do the unpacking..
  1367. @docstring.dedent_interpd
  1368. def loglog(self, *args, **kwargs):
  1369. """
  1370. Make a plot with log scaling on both the x and y axis.
  1371. Call signatures::
  1372. loglog([x], y, [fmt], data=None, **kwargs)
  1373. loglog([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)
  1374. This is just a thin wrapper around `.plot` which additionally changes
  1375. both the x-axis and the y-axis to log scaling. All of the concepts and
  1376. parameters of plot can be used here as well.
  1377. The additional parameters *basex/y*, *subsx/y* and *nonposx/y* control
  1378. the x/y-axis properties. They are just forwarded to `.Axes.set_xscale`
  1379. and `.Axes.set_yscale`.
  1380. Parameters
  1381. ----------
  1382. basex, basey : scalar, optional, default 10
  1383. Base of the x/y logarithm.
  1384. subsx, subsy : sequence, optional
  1385. The location of the minor x/y ticks. If *None*, reasonable
  1386. locations are automatically chosen depending on the number of
  1387. decades in the plot.
  1388. See `.Axes.set_xscale` / `.Axes.set_yscale` for details.
  1389. nonposx, nonposy : {'mask', 'clip'}, optional, default 'mask'
  1390. Non-positive values in x or y can be masked as invalid, or clipped
  1391. to a very small positive number.
  1392. Returns
  1393. -------
  1394. lines
  1395. A list of `.Line2D` objects representing the plotted data.
  1396. Other Parameters
  1397. ----------------
  1398. **kwargs
  1399. All parameters supported by `.plot`.
  1400. """
  1401. dx = {k: kwargs.pop(k) for k in ['basex', 'subsx', 'nonposx']
  1402. if k in kwargs}
  1403. dy = {k: kwargs.pop(k) for k in ['basey', 'subsy', 'nonposy']
  1404. if k in kwargs}
  1405. self.set_xscale('log', **dx)
  1406. self.set_yscale('log', **dy)
  1407. l = self.plot(*args, **kwargs)
  1408. return l
  1409. # @_preprocess_data() # let 'plot' do the unpacking..
  1410. @docstring.dedent_interpd
  1411. def semilogx(self, *args, **kwargs):
  1412. """
  1413. Make a plot with log scaling on the x axis.
  1414. Call signatures::
  1415. semilogx([x], y, [fmt], data=None, **kwargs)
  1416. semilogx([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)
  1417. This is just a thin wrapper around `.plot` which additionally changes
  1418. the x-axis to log scaling. All of the concepts and parameters of plot
  1419. can be used here as well.
  1420. The additional parameters *basex*, *subsx* and *nonposx* control the
  1421. x-axis properties. They are just forwarded to `.Axes.set_xscale`.
  1422. Parameters
  1423. ----------
  1424. basex : scalar, optional, default 10
  1425. Base of the x logarithm.
  1426. subsx : array-like, optional
  1427. The location of the minor xticks. If *None*, reasonable locations
  1428. are automatically chosen depending on the number of decades in the
  1429. plot. See `.Axes.set_xscale` for details.
  1430. nonposx : {'mask', 'clip'}, optional, default 'mask'
  1431. Non-positive values in x can be masked as invalid, or clipped to a
  1432. very small positive number.
  1433. Returns
  1434. -------
  1435. lines
  1436. A list of `.Line2D` objects representing the plotted data.
  1437. Other Parameters
  1438. ----------------
  1439. **kwargs
  1440. All parameters supported by `.plot`.
  1441. """
  1442. d = {k: kwargs.pop(k) for k in ['basex', 'subsx', 'nonposx']
  1443. if k in kwargs}
  1444. self.set_xscale('log', **d)
  1445. l = self.plot(*args, **kwargs)
  1446. return l
  1447. # @_preprocess_data() # let 'plot' do the unpacking..
  1448. @docstring.dedent_interpd
  1449. def semilogy(self, *args, **kwargs):
  1450. """
  1451. Make a plot with log scaling on the y axis.
  1452. Call signatures::
  1453. semilogy([x], y, [fmt], data=None, **kwargs)
  1454. semilogy([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)
  1455. This is just a thin wrapper around `.plot` which additionally changes
  1456. the y-axis to log scaling. All of the concepts and parameters of plot
  1457. can be used here as well.
  1458. The additional parameters *basey*, *subsy* and *nonposy* control the
  1459. y-axis properties. They are just forwarded to `.Axes.set_yscale`.
  1460. Parameters
  1461. ----------
  1462. basey : scalar, optional, default 10
  1463. Base of the y logarithm.
  1464. subsy : array-like, optional
  1465. The location of the minor yticks. If *None*, reasonable locations
  1466. are automatically chosen depending on the number of decades in the
  1467. plot. See `.Axes.set_yscale` for details.
  1468. nonposy : {'mask', 'clip'}, optional, default 'mask'
  1469. Non-positive values in y can be masked as invalid, or clipped to a
  1470. very small positive number.
  1471. Returns
  1472. -------
  1473. lines
  1474. A list of `.Line2D` objects representing the plotted data.
  1475. Other Parameters
  1476. ----------------
  1477. **kwargs
  1478. All parameters supported by `.plot`.
  1479. """
  1480. d = {k: kwargs.pop(k) for k in ['basey', 'subsy', 'nonposy']
  1481. if k in kwargs}
  1482. self.set_yscale('log', **d)
  1483. l = self.plot(*args, **kwargs)
  1484. return l
  1485. @_preprocess_data(replace_names=["x"], label_namer="x")
  1486. def acorr(self, x, **kwargs):
  1487. """
  1488. Plot the autocorrelation of *x*.
  1489. Parameters
  1490. ----------
  1491. x : array-like
  1492. detrend : callable, optional, default: `mlab.detrend_none`
  1493. *x* is detrended by the *detrend* callable. This must be a
  1494. function ``x = detrend(x)`` accepting and returning an
  1495. `numpy.array`. Default is no normalization.
  1496. normed : bool, optional, default: True
  1497. If ``True``, input vectors are normalised to unit length.
  1498. usevlines : bool, optional, default: True
  1499. Determines the plot style.
  1500. If ``True``, vertical lines are plotted from 0 to the acorr value
  1501. using `Axes.vlines`. Additionally, a horizontal line is plotted
  1502. at y=0 using `Axes.axhline`.
  1503. If ``False``, markers are plotted at the acorr values using
  1504. `Axes.plot`.
  1505. maxlags : int, optional, default: 10
  1506. Number of lags to show. If ``None``, will return all
  1507. ``2 * len(x) - 1`` lags.
  1508. Returns
  1509. -------
  1510. lags : array (length ``2*maxlags+1``)
  1511. The lag vector.
  1512. c : array (length ``2*maxlags+1``)
  1513. The auto correlation vector.
  1514. line : `.LineCollection` or `.Line2D`
  1515. `.Artist` added to the axes of the correlation:
  1516. - `.LineCollection` if *usevlines* is True.
  1517. - `.Line2D` if *usevlines* is False.
  1518. b : `.Line2D` or None
  1519. Horizontal line at 0 if *usevlines* is True
  1520. None *usevlines* is False.
  1521. Other Parameters
  1522. ----------------
  1523. linestyle : `.Line2D` property, optional
  1524. The linestyle for plotting the data points.
  1525. Only used if *usevlines* is ``False``.
  1526. marker : str, optional, default: 'o'
  1527. The marker for plotting the data points.
  1528. Only used if *usevlines* is ``False``.
  1529. Notes
  1530. -----
  1531. The cross correlation is performed with :func:`numpy.correlate` with
  1532. ``mode = "full"``.
  1533. """
  1534. return self.xcorr(x, x, **kwargs)
  1535. @_preprocess_data(replace_names=["x", "y"], label_namer="y")
  1536. def xcorr(self, x, y, normed=True, detrend=mlab.detrend_none,
  1537. usevlines=True, maxlags=10, **kwargs):
  1538. r"""
  1539. Plot the cross correlation between *x* and *y*.
  1540. The correlation with lag k is defined as
  1541. :math:`\sum_n x[n+k] \cdot y^*[n]`, where :math:`y^*` is the complex
  1542. conjugate of :math:`y`.
  1543. Parameters
  1544. ----------
  1545. x : array-like of length n
  1546. y : array-like of length n
  1547. detrend : callable, optional, default: `mlab.detrend_none`
  1548. *x* and *y* are detrended by the *detrend* callable. This must be a
  1549. function ``x = detrend(x)`` accepting and returning an
  1550. `numpy.array`. Default is no normalization.
  1551. normed : bool, optional, default: True
  1552. If ``True``, input vectors are normalised to unit length.
  1553. usevlines : bool, optional, default: True
  1554. Determines the plot style.
  1555. If ``True``, vertical lines are plotted from 0 to the xcorr value
  1556. using `Axes.vlines`. Additionally, a horizontal line is plotted
  1557. at y=0 using `Axes.axhline`.
  1558. If ``False``, markers are plotted at the xcorr values using
  1559. `Axes.plot`.
  1560. maxlags : int, optional, default: 10
  1561. Number of lags to show. If None, will return all ``2 * len(x) - 1``
  1562. lags.
  1563. Returns
  1564. -------
  1565. lags : array (length ``2*maxlags+1``)
  1566. The lag vector.
  1567. c : array (length ``2*maxlags+1``)
  1568. The auto correlation vector.
  1569. line : `.LineCollection` or `.Line2D`
  1570. `.Artist` added to the axes of the correlation:
  1571. - `.LineCollection` if *usevlines* is True.
  1572. - `.Line2D` if *usevlines* is False.
  1573. b : `.Line2D` or None
  1574. Horizontal line at 0 if *usevlines* is True
  1575. None *usevlines* is False.
  1576. Other Parameters
  1577. ----------------
  1578. linestyle : `.Line2D` property, optional
  1579. The linestyle for plotting the data points.
  1580. Only used if *usevlines* is ``False``.
  1581. marker : str, optional, default: 'o'
  1582. The marker for plotting the data points.
  1583. Only used if *usevlines* is ``False``.
  1584. Notes
  1585. -----
  1586. The cross correlation is performed with :func:`numpy.correlate` with
  1587. ``mode = "full"``.
  1588. """
  1589. Nx = len(x)
  1590. if Nx != len(y):
  1591. raise ValueError('x and y must be equal length')
  1592. x = detrend(np.asarray(x))
  1593. y = detrend(np.asarray(y))
  1594. correls = np.correlate(x, y, mode="full")
  1595. if normed:
  1596. correls /= np.sqrt(np.dot(x, x) * np.dot(y, y))
  1597. if maxlags is None:
  1598. maxlags = Nx - 1
  1599. if maxlags >= Nx or maxlags < 1:
  1600. raise ValueError('maxlags must be None or strictly '
  1601. 'positive < %d' % Nx)
  1602. lags = np.arange(-maxlags, maxlags + 1)
  1603. correls = correls[Nx - 1 - maxlags:Nx + maxlags]
  1604. if usevlines:
  1605. a = self.vlines(lags, [0], correls, **kwargs)
  1606. # Make label empty so only vertical lines get a legend entry
  1607. kwargs.pop('label', '')
  1608. b = self.axhline(**kwargs)
  1609. else:
  1610. kwargs.setdefault('marker', 'o')
  1611. kwargs.setdefault('linestyle', 'None')
  1612. a, = self.plot(lags, correls, **kwargs)
  1613. b = None
  1614. return lags, correls, a, b
  1615. #### Specialized plotting
  1616. # @_preprocess_data() # let 'plot' do the unpacking..
  1617. def step(self, x, y, *args, where='pre', data=None, **kwargs):
  1618. """
  1619. Make a step plot.
  1620. Call signatures::
  1621. step(x, y, [fmt], *, data=None, where='pre', **kwargs)
  1622. step(x, y, [fmt], x2, y2, [fmt2], ..., *, where='pre', **kwargs)
  1623. This is just a thin wrapper around `.plot` which changes some
  1624. formatting options. Most of the concepts and parameters of plot can be
  1625. used here as well.
  1626. Parameters
  1627. ----------
  1628. x : array-like
  1629. 1-D sequence of x positions. It is assumed, but not checked, that
  1630. it is uniformly increasing.
  1631. y : array-like
  1632. 1-D sequence of y levels.
  1633. fmt : str, optional
  1634. A format string, e.g. 'g' for a green line. See `.plot` for a more
  1635. detailed description.
  1636. Note: While full format strings are accepted, it is recommended to
  1637. only specify the color. Line styles are currently ignored (use
  1638. the keyword argument *linestyle* instead). Markers are accepted
  1639. and plotted on the given positions, however, this is a rarely
  1640. needed feature for step plots.
  1641. data : indexable object, optional
  1642. An object with labelled data. If given, provide the label names to
  1643. plot in *x* and *y*.
  1644. where : {'pre', 'post', 'mid'}, optional, default 'pre'
  1645. Define where the steps should be placed:
  1646. - 'pre': The y value is continued constantly to the left from
  1647. every *x* position, i.e. the interval ``(x[i-1], x[i]]`` has the
  1648. value ``y[i]``.
  1649. - 'post': The y value is continued constantly to the right from
  1650. every *x* position, i.e. the interval ``[x[i], x[i+1])`` has the
  1651. value ``y[i]``.
  1652. - 'mid': Steps occur half-way between the *x* positions.
  1653. Returns
  1654. -------
  1655. lines
  1656. A list of `.Line2D` objects representing the plotted data.
  1657. Other Parameters
  1658. ----------------
  1659. **kwargs
  1660. Additional parameters are the same as those for `.plot`.
  1661. Notes
  1662. -----
  1663. .. [notes section required to get data note injection right]
  1664. """
  1665. cbook._check_in_list(('pre', 'post', 'mid'), where=where)
  1666. kwargs['drawstyle'] = 'steps-' + where
  1667. return self.plot(x, y, *args, data=data, **kwargs)
  1668. @staticmethod
  1669. def _convert_dx(dx, x0, xconv, convert):
  1670. """
  1671. Small helper to do logic of width conversion flexibly.
  1672. *dx* and *x0* have units, but *xconv* has already been converted
  1673. to unitless (and is an ndarray). This allows the *dx* to have units
  1674. that are different from *x0*, but are still accepted by the
  1675. ``__add__`` operator of *x0*.
  1676. """
  1677. # x should be an array...
  1678. assert type(xconv) is np.ndarray
  1679. if xconv.size == 0:
  1680. # xconv has already been converted, but maybe empty...
  1681. return convert(dx)
  1682. try:
  1683. # attempt to add the width to x0; this works for
  1684. # datetime+timedelta, for instance
  1685. # only use the first element of x and x0. This saves
  1686. # having to be sure addition works across the whole
  1687. # vector. This is particularly an issue if
  1688. # x0 and dx are lists so x0 + dx just concatenates the lists.
  1689. # We can't just cast x0 and dx to numpy arrays because that
  1690. # removes the units from unit packages like `pint` that
  1691. # wrap numpy arrays.
  1692. try:
  1693. x0 = cbook.safe_first_element(x0)
  1694. except (TypeError, IndexError, KeyError):
  1695. x0 = x0
  1696. try:
  1697. x = cbook.safe_first_element(xconv)
  1698. except (TypeError, IndexError, KeyError):
  1699. x = xconv
  1700. delist = False
  1701. if not np.iterable(dx):
  1702. dx = [dx]
  1703. delist = True
  1704. dx = [convert(x0 + ddx) - x for ddx in dx]
  1705. if delist:
  1706. dx = dx[0]
  1707. except (ValueError, TypeError, AttributeError):
  1708. # if the above fails (for any reason) just fallback to what
  1709. # we do by default and convert dx by itself.
  1710. dx = convert(dx)
  1711. return dx
  1712. @_preprocess_data()
  1713. @docstring.dedent_interpd
  1714. def bar(self, x, height, width=0.8, bottom=None, *, align="center",
  1715. **kwargs):
  1716. r"""
  1717. Make a bar plot.
  1718. The bars are positioned at *x* with the given *align*\ment. Their
  1719. dimensions are given by *width* and *height*. The vertical baseline
  1720. is *bottom* (default 0).
  1721. Each of *x*, *height*, *width*, and *bottom* may either be a scalar
  1722. applying to all bars, or it may be a sequence of length N providing a
  1723. separate value for each bar.
  1724. Parameters
  1725. ----------
  1726. x : sequence of scalars
  1727. The x coordinates of the bars. See also *align* for the
  1728. alignment of the bars to the coordinates.
  1729. height : scalar or sequence of scalars
  1730. The height(s) of the bars.
  1731. width : scalar or array-like, optional
  1732. The width(s) of the bars (default: 0.8).
  1733. bottom : scalar or array-like, optional
  1734. The y coordinate(s) of the bars bases (default: 0).
  1735. align : {'center', 'edge'}, optional, default: 'center'
  1736. Alignment of the bars to the *x* coordinates:
  1737. - 'center': Center the base on the *x* positions.
  1738. - 'edge': Align the left edges of the bars with the *x* positions.
  1739. To align the bars on the right edge pass a negative *width* and
  1740. ``align='edge'``.
  1741. Returns
  1742. -------
  1743. container : `.BarContainer`
  1744. Container with all the bars and optionally errorbars.
  1745. Other Parameters
  1746. ----------------
  1747. color : scalar or array-like, optional
  1748. The colors of the bar faces.
  1749. edgecolor : scalar or array-like, optional
  1750. The colors of the bar edges.
  1751. linewidth : scalar or array-like, optional
  1752. Width of the bar edge(s). If 0, don't draw edges.
  1753. tick_label : str or array-like, optional
  1754. The tick labels of the bars.
  1755. Default: None (Use default numeric labels.)
  1756. xerr, yerr : scalar or array-like of shape(N,) or shape(2, N), optional
  1757. If not *None*, add horizontal / vertical errorbars to the bar tips.
  1758. The values are +/- sizes relative to the data:
  1759. - scalar: symmetric +/- values for all bars
  1760. - shape(N,): symmetric +/- values for each bar
  1761. - shape(2, N): Separate - and + values for each bar. First row
  1762. contains the lower errors, the second row contains the upper
  1763. errors.
  1764. - *None*: No errorbar. (Default)
  1765. See :doc:`/gallery/statistics/errorbar_features`
  1766. for an example on the usage of ``xerr`` and ``yerr``.
  1767. ecolor : scalar or array-like, optional, default: 'black'
  1768. The line color of the errorbars.
  1769. capsize : scalar, optional
  1770. The length of the error bar caps in points.
  1771. Default: None, which will take the value from
  1772. :rc:`errorbar.capsize`.
  1773. error_kw : dict, optional
  1774. Dictionary of kwargs to be passed to the `~.Axes.errorbar`
  1775. method. Values of *ecolor* or *capsize* defined here take
  1776. precedence over the independent kwargs.
  1777. log : bool, optional, default: False
  1778. If *True*, set the y-axis to be log scale.
  1779. orientation : {'vertical', 'horizontal'}, optional
  1780. *This is for internal use only.* Please use `barh` for
  1781. horizontal bar plots. Default: 'vertical'.
  1782. See also
  1783. --------
  1784. barh: Plot a horizontal bar plot.
  1785. Notes
  1786. -----
  1787. The optional arguments *color*, *edgecolor*, *linewidth*,
  1788. *xerr*, and *yerr* can be either scalars or sequences of
  1789. length equal to the number of bars. This enables you to use
  1790. bar as the basis for stacked bar charts, or candlestick plots.
  1791. Detail: *xerr* and *yerr* are passed directly to
  1792. :meth:`errorbar`, so they can also have shape 2xN for
  1793. independent specification of lower and upper errors.
  1794. Other optional kwargs:
  1795. %(Rectangle)s
  1796. """
  1797. kwargs = cbook.normalize_kwargs(kwargs, mpatches.Patch)
  1798. color = kwargs.pop('color', None)
  1799. if color is None:
  1800. color = self._get_patches_for_fill.get_next_color()
  1801. edgecolor = kwargs.pop('edgecolor', None)
  1802. linewidth = kwargs.pop('linewidth', None)
  1803. # Because xerr and yerr will be passed to errorbar, most dimension
  1804. # checking and processing will be left to the errorbar method.
  1805. xerr = kwargs.pop('xerr', None)
  1806. yerr = kwargs.pop('yerr', None)
  1807. error_kw = kwargs.pop('error_kw', {})
  1808. ezorder = error_kw.pop('zorder', None)
  1809. if ezorder is None:
  1810. ezorder = kwargs.get('zorder', None)
  1811. if ezorder is not None:
  1812. # If using the bar zorder, increment slightly to make sure
  1813. # errorbars are drawn on top of bars
  1814. ezorder += 0.01
  1815. error_kw.setdefault('zorder', ezorder)
  1816. ecolor = kwargs.pop('ecolor', 'k')
  1817. capsize = kwargs.pop('capsize', rcParams["errorbar.capsize"])
  1818. error_kw.setdefault('ecolor', ecolor)
  1819. error_kw.setdefault('capsize', capsize)
  1820. orientation = kwargs.pop('orientation', 'vertical')
  1821. cbook._check_in_list(['vertical', 'horizontal'],
  1822. orientation=orientation)
  1823. log = kwargs.pop('log', False)
  1824. label = kwargs.pop('label', '')
  1825. tick_labels = kwargs.pop('tick_label', None)
  1826. y = bottom # Matches barh call signature.
  1827. if orientation == 'vertical':
  1828. if y is None:
  1829. y = 0
  1830. elif orientation == 'horizontal':
  1831. if x is None:
  1832. x = 0
  1833. if orientation == 'vertical':
  1834. self._process_unit_info(xdata=x, ydata=height, kwargs=kwargs)
  1835. if log:
  1836. self.set_yscale('log', nonposy='clip')
  1837. elif orientation == 'horizontal':
  1838. self._process_unit_info(xdata=width, ydata=y, kwargs=kwargs)
  1839. if log:
  1840. self.set_xscale('log', nonposx='clip')
  1841. # lets do some conversions now since some types cannot be
  1842. # subtracted uniformly
  1843. if self.xaxis is not None:
  1844. x0 = x
  1845. x = np.asarray(self.convert_xunits(x))
  1846. width = self._convert_dx(width, x0, x, self.convert_xunits)
  1847. if xerr is not None:
  1848. xerr = self._convert_dx(xerr, x0, x, self.convert_xunits)
  1849. if self.yaxis is not None:
  1850. y0 = y
  1851. y = np.asarray(self.convert_yunits(y))
  1852. height = self._convert_dx(height, y0, y, self.convert_yunits)
  1853. if yerr is not None:
  1854. yerr = self._convert_dx(yerr, y0, y, self.convert_yunits)
  1855. x, height, width, y, linewidth = np.broadcast_arrays(
  1856. # Make args iterable too.
  1857. np.atleast_1d(x), height, width, y, linewidth)
  1858. # Now that units have been converted, set the tick locations.
  1859. if orientation == 'vertical':
  1860. tick_label_axis = self.xaxis
  1861. tick_label_position = x
  1862. elif orientation == 'horizontal':
  1863. tick_label_axis = self.yaxis
  1864. tick_label_position = y
  1865. linewidth = itertools.cycle(np.atleast_1d(linewidth))
  1866. color = itertools.chain(itertools.cycle(mcolors.to_rgba_array(color)),
  1867. # Fallback if color == "none".
  1868. itertools.repeat('none'))
  1869. if edgecolor is None:
  1870. edgecolor = itertools.repeat(None)
  1871. else:
  1872. edgecolor = itertools.chain(
  1873. itertools.cycle(mcolors.to_rgba_array(edgecolor)),
  1874. # Fallback if edgecolor == "none".
  1875. itertools.repeat('none'))
  1876. # We will now resolve the alignment and really have
  1877. # left, bottom, width, height vectors
  1878. cbook._check_in_list(['center', 'edge'], align=align)
  1879. if align == 'center':
  1880. if orientation == 'vertical':
  1881. try:
  1882. left = x - width / 2
  1883. except TypeError as e:
  1884. raise TypeError(f'the dtypes of parameters x ({x.dtype}) '
  1885. f'and width ({width.dtype}) '
  1886. f'are incompatible') from e
  1887. bottom = y
  1888. elif orientation == 'horizontal':
  1889. try:
  1890. bottom = y - height / 2
  1891. except TypeError as e:
  1892. raise TypeError(f'the dtypes of parameters y ({y.dtype}) '
  1893. f'and height ({height.dtype}) '
  1894. f'are incompatible') from e
  1895. left = x
  1896. elif align == 'edge':
  1897. left = x
  1898. bottom = y
  1899. patches = []
  1900. args = zip(left, bottom, width, height, color, edgecolor, linewidth)
  1901. for l, b, w, h, c, e, lw in args:
  1902. r = mpatches.Rectangle(
  1903. xy=(l, b), width=w, height=h,
  1904. facecolor=c,
  1905. edgecolor=e,
  1906. linewidth=lw,
  1907. label='_nolegend_',
  1908. )
  1909. r.update(kwargs)
  1910. r.get_path()._interpolation_steps = 100
  1911. if orientation == 'vertical':
  1912. r.sticky_edges.y.append(b)
  1913. elif orientation == 'horizontal':
  1914. r.sticky_edges.x.append(l)
  1915. self.add_patch(r)
  1916. patches.append(r)
  1917. if xerr is not None or yerr is not None:
  1918. if orientation == 'vertical':
  1919. # using list comps rather than arrays to preserve unit info
  1920. ex = [l + 0.5 * w for l, w in zip(left, width)]
  1921. ey = [b + h for b, h in zip(bottom, height)]
  1922. elif orientation == 'horizontal':
  1923. # using list comps rather than arrays to preserve unit info
  1924. ex = [l + w for l, w in zip(left, width)]
  1925. ey = [b + 0.5 * h for b, h in zip(bottom, height)]
  1926. error_kw.setdefault("label", '_nolegend_')
  1927. errorbar = self.errorbar(ex, ey,
  1928. yerr=yerr, xerr=xerr,
  1929. fmt='none', **error_kw)
  1930. else:
  1931. errorbar = None
  1932. self._request_autoscale_view()
  1933. bar_container = BarContainer(patches, errorbar, label=label)
  1934. self.add_container(bar_container)
  1935. if tick_labels is not None:
  1936. tick_labels = np.broadcast_to(tick_labels, len(patches))
  1937. tick_label_axis.set_ticks(tick_label_position)
  1938. tick_label_axis.set_ticklabels(tick_labels)
  1939. return bar_container
  1940. @docstring.dedent_interpd
  1941. def barh(self, y, width, height=0.8, left=None, *, align="center",
  1942. **kwargs):
  1943. r"""
  1944. Make a horizontal bar plot.
  1945. The bars are positioned at *y* with the given *align*\ment. Their
  1946. dimensions are given by *width* and *height*. The horizontal baseline
  1947. is *left* (default 0).
  1948. Each of *y*, *width*, *height*, and *left* may either be a scalar
  1949. applying to all bars, or it may be a sequence of length N providing a
  1950. separate value for each bar.
  1951. Parameters
  1952. ----------
  1953. y : scalar or array-like
  1954. The y coordinates of the bars. See also *align* for the
  1955. alignment of the bars to the coordinates.
  1956. width : scalar or array-like
  1957. The width(s) of the bars.
  1958. height : sequence of scalars, optional, default: 0.8
  1959. The heights of the bars.
  1960. left : sequence of scalars
  1961. The x coordinates of the left sides of the bars (default: 0).
  1962. align : {'center', 'edge'}, optional, default: 'center'
  1963. Alignment of the base to the *y* coordinates*:
  1964. - 'center': Center the bars on the *y* positions.
  1965. - 'edge': Align the bottom edges of the bars with the *y*
  1966. positions.
  1967. To align the bars on the top edge pass a negative *height* and
  1968. ``align='edge'``.
  1969. Returns
  1970. -------
  1971. container : `.BarContainer`
  1972. Container with all the bars and optionally errorbars.
  1973. Other Parameters
  1974. ----------------
  1975. color : scalar or array-like, optional
  1976. The colors of the bar faces.
  1977. edgecolor : scalar or array-like, optional
  1978. The colors of the bar edges.
  1979. linewidth : scalar or array-like, optional
  1980. Width of the bar edge(s). If 0, don't draw edges.
  1981. tick_label : str or array-like, optional
  1982. The tick labels of the bars.
  1983. Default: None (Use default numeric labels.)
  1984. xerr, yerr : scalar or array-like of shape(N,) or shape(2, N), optional
  1985. If not ``None``, add horizontal / vertical errorbars to the
  1986. bar tips. The values are +/- sizes relative to the data:
  1987. - scalar: symmetric +/- values for all bars
  1988. - shape(N,): symmetric +/- values for each bar
  1989. - shape(2, N): Separate - and + values for each bar. First row
  1990. contains the lower errors, the second row contains the upper
  1991. errors.
  1992. - *None*: No errorbar. (default)
  1993. See :doc:`/gallery/statistics/errorbar_features`
  1994. for an example on the usage of ``xerr`` and ``yerr``.
  1995. ecolor : scalar or array-like, optional, default: 'black'
  1996. The line color of the errorbars.
  1997. capsize : scalar, optional
  1998. The length of the error bar caps in points.
  1999. Default: None, which will take the value from
  2000. :rc:`errorbar.capsize`.
  2001. error_kw : dict, optional
  2002. Dictionary of kwargs to be passed to the `~.Axes.errorbar`
  2003. method. Values of *ecolor* or *capsize* defined here take
  2004. precedence over the independent kwargs.
  2005. log : bool, optional, default: False
  2006. If ``True``, set the x-axis to be log scale.
  2007. See also
  2008. --------
  2009. bar: Plot a vertical bar plot.
  2010. Notes
  2011. -----
  2012. The optional arguments *color*, *edgecolor*, *linewidth*,
  2013. *xerr*, and *yerr* can be either scalars or sequences of
  2014. length equal to the number of bars. This enables you to use
  2015. bar as the basis for stacked bar charts, or candlestick plots.
  2016. Detail: *xerr* and *yerr* are passed directly to
  2017. :meth:`errorbar`, so they can also have shape 2xN for
  2018. independent specification of lower and upper errors.
  2019. Other optional kwargs:
  2020. %(Rectangle)s
  2021. """
  2022. kwargs.setdefault('orientation', 'horizontal')
  2023. patches = self.bar(x=left, height=height, width=width, bottom=y,
  2024. align=align, **kwargs)
  2025. return patches
  2026. @_preprocess_data()
  2027. @docstring.dedent_interpd
  2028. def broken_barh(self, xranges, yrange, **kwargs):
  2029. """
  2030. Plot a horizontal sequence of rectangles.
  2031. A rectangle is drawn for each element of *xranges*. All rectangles
  2032. have the same vertical position and size defined by *yrange*.
  2033. This is a convenience function for instantiating a
  2034. `.BrokenBarHCollection`, adding it to the axes and autoscaling the
  2035. view.
  2036. Parameters
  2037. ----------
  2038. xranges : sequence of tuples (*xmin*, *xwidth*)
  2039. The x-positions and extends of the rectangles. For each tuple
  2040. (*xmin*, *xwidth*) a rectangle is drawn from *xmin* to *xmin* +
  2041. *xwidth*.
  2042. yrange : (*ymin*, *yheight*)
  2043. The y-position and extend for all the rectangles.
  2044. Other Parameters
  2045. ----------------
  2046. **kwargs : :class:`.BrokenBarHCollection` properties
  2047. Each *kwarg* can be either a single argument applying to all
  2048. rectangles, e.g.::
  2049. facecolors='black'
  2050. or a sequence of arguments over which is cycled, e.g.::
  2051. facecolors=('black', 'blue')
  2052. would create interleaving black and blue rectangles.
  2053. Supported keywords:
  2054. %(BrokenBarHCollection)s
  2055. Returns
  2056. -------
  2057. collection : A :class:`~.collections.BrokenBarHCollection`
  2058. """
  2059. # process the unit information
  2060. if len(xranges):
  2061. xdata = cbook.safe_first_element(xranges)
  2062. else:
  2063. xdata = None
  2064. if len(yrange):
  2065. ydata = cbook.safe_first_element(yrange)
  2066. else:
  2067. ydata = None
  2068. self._process_unit_info(xdata=xdata,
  2069. ydata=ydata,
  2070. kwargs=kwargs)
  2071. xranges_conv = []
  2072. for xr in xranges:
  2073. if len(xr) != 2:
  2074. raise ValueError('each range in xrange must be a sequence '
  2075. 'with two elements (i.e. an Nx2 array)')
  2076. # convert the absolute values, not the x and dx...
  2077. x_conv = np.asarray(self.convert_xunits(xr[0]))
  2078. x1 = self._convert_dx(xr[1], xr[0], x_conv, self.convert_xunits)
  2079. xranges_conv.append((x_conv, x1))
  2080. yrange_conv = self.convert_yunits(yrange)
  2081. col = mcoll.BrokenBarHCollection(xranges_conv, yrange_conv, **kwargs)
  2082. self.add_collection(col, autolim=True)
  2083. self._request_autoscale_view()
  2084. return col
  2085. @_preprocess_data()
  2086. def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0,
  2087. label=None, use_line_collection=False):
  2088. """
  2089. Create a stem plot.
  2090. A stem plot plots vertical lines at each *x* location from the baseline
  2091. to *y*, and places a marker there.
  2092. Call signature::
  2093. stem([x,] y, linefmt=None, markerfmt=None, basefmt=None)
  2094. The x-positions are optional. The formats may be provided either as
  2095. positional or as keyword-arguments.
  2096. Parameters
  2097. ----------
  2098. x : array-like, optional
  2099. The x-positions of the stems. Default: (0, 1, ..., len(y) - 1).
  2100. y : array-like
  2101. The y-values of the stem heads.
  2102. linefmt : str, optional
  2103. A string defining the properties of the vertical lines. Usually,
  2104. this will be a color or a color and a linestyle:
  2105. ========= =============
  2106. Character Line Style
  2107. ========= =============
  2108. ``'-'`` solid line
  2109. ``'--'`` dashed line
  2110. ``'-.'`` dash-dot line
  2111. ``':'`` dotted line
  2112. ========= =============
  2113. Default: 'C0-', i.e. solid line with the first color of the color
  2114. cycle.
  2115. Note: While it is technically possible to specify valid formats
  2116. other than color or color and linestyle (e.g. 'rx' or '-.'), this
  2117. is beyond the intention of the method and will most likely not
  2118. result in a reasonable reasonable plot.
  2119. markerfmt : str, optional
  2120. A string defining the properties of the markers at the stem heads.
  2121. Default: 'C0o', i.e. filled circles with the first color of the
  2122. color cycle.
  2123. basefmt : str, optional
  2124. A format string defining the properties of the baseline.
  2125. Default: 'C3-' ('C2-' in classic mode).
  2126. bottom : float, optional, default: 0
  2127. The y-position of the baseline.
  2128. label : str, optional, default: None
  2129. The label to use for the stems in legends.
  2130. use_line_collection : bool, optional, default: False
  2131. If ``True``, store and plot the stem lines as a
  2132. `~.collections.LineCollection` instead of individual lines. This
  2133. significantly increases performance, and will become the default
  2134. option in Matplotlib 3.3. If ``False``, defaults to the old
  2135. behavior of using a list of `.Line2D` objects.
  2136. Returns
  2137. -------
  2138. container : :class:`~matplotlib.container.StemContainer`
  2139. The container may be treated like a tuple
  2140. (*markerline*, *stemlines*, *baseline*)
  2141. Notes
  2142. -----
  2143. .. seealso::
  2144. The MATLAB function
  2145. `stem <http://www.mathworks.com/help/techdoc/ref/stem.html>`_
  2146. which inspired this method.
  2147. """
  2148. if not 1 <= len(args) <= 5:
  2149. raise TypeError('stem expected between 1 and 5 positional '
  2150. 'arguments, got {}'.format(args))
  2151. if len(args) == 1:
  2152. y, = args
  2153. x = np.arange(len(y))
  2154. args = ()
  2155. else:
  2156. x, y, *args = args
  2157. self._process_unit_info(xdata=x, ydata=y)
  2158. x = self.convert_xunits(x)
  2159. y = self.convert_yunits(y)
  2160. # defaults for formats
  2161. if linefmt is None:
  2162. try:
  2163. # fallback to positional argument
  2164. linefmt = args[0]
  2165. except IndexError:
  2166. linecolor = 'C0'
  2167. linemarker = 'None'
  2168. linestyle = '-'
  2169. else:
  2170. linestyle, linemarker, linecolor = \
  2171. _process_plot_format(linefmt)
  2172. else:
  2173. linestyle, linemarker, linecolor = _process_plot_format(linefmt)
  2174. if markerfmt is None:
  2175. try:
  2176. # fallback to positional argument
  2177. markerfmt = args[1]
  2178. except IndexError:
  2179. markercolor = 'C0'
  2180. markermarker = 'o'
  2181. markerstyle = 'None'
  2182. else:
  2183. markerstyle, markermarker, markercolor = \
  2184. _process_plot_format(markerfmt)
  2185. else:
  2186. markerstyle, markermarker, markercolor = \
  2187. _process_plot_format(markerfmt)
  2188. if basefmt is None:
  2189. try:
  2190. # fallback to positional argument
  2191. basefmt = args[2]
  2192. except IndexError:
  2193. if rcParams['_internal.classic_mode']:
  2194. basecolor = 'C2'
  2195. else:
  2196. basecolor = 'C3'
  2197. basemarker = 'None'
  2198. basestyle = '-'
  2199. else:
  2200. basestyle, basemarker, basecolor = \
  2201. _process_plot_format(basefmt)
  2202. else:
  2203. basestyle, basemarker, basecolor = _process_plot_format(basefmt)
  2204. # New behaviour in 3.1 is to use a LineCollection for the stemlines
  2205. if use_line_collection:
  2206. stemlines = [((xi, bottom), (xi, yi)) for xi, yi in zip(x, y)]
  2207. if linestyle is None:
  2208. linestyle = rcParams['lines.linestyle']
  2209. stemlines = mcoll.LineCollection(stemlines, linestyles=linestyle,
  2210. colors=linecolor,
  2211. label='_nolegend_')
  2212. self.add_collection(stemlines)
  2213. # Old behaviour is to plot each of the lines individually
  2214. else:
  2215. cbook._warn_external(
  2216. 'In Matplotlib 3.3 individual lines on a stem plot will be '
  2217. 'added as a LineCollection instead of individual lines. '
  2218. 'This significantly improves the performance of a stem plot. '
  2219. 'To remove this warning and switch to the new behaviour, '
  2220. 'set the "use_line_collection" keyword argument to True.')
  2221. stemlines = []
  2222. for xi, yi in zip(x, y):
  2223. l, = self.plot([xi, xi], [bottom, yi],
  2224. color=linecolor, linestyle=linestyle,
  2225. marker=linemarker, label="_nolegend_")
  2226. stemlines.append(l)
  2227. markerline, = self.plot(x, y, color=markercolor, linestyle=markerstyle,
  2228. marker=markermarker, label="_nolegend_")
  2229. baseline, = self.plot([np.min(x), np.max(x)], [bottom, bottom],
  2230. color=basecolor, linestyle=basestyle,
  2231. marker=basemarker, label="_nolegend_")
  2232. stem_container = StemContainer((markerline, stemlines, baseline),
  2233. label=label)
  2234. self.add_container(stem_container)
  2235. return stem_container
  2236. @_preprocess_data(replace_names=["x", "explode", "labels", "colors"])
  2237. def pie(self, x, explode=None, labels=None, colors=None,
  2238. autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1,
  2239. startangle=None, radius=None, counterclock=True,
  2240. wedgeprops=None, textprops=None, center=(0, 0),
  2241. frame=False, rotatelabels=False):
  2242. """
  2243. Plot a pie chart.
  2244. Make a pie chart of array *x*. The fractional area of each wedge is
  2245. given by ``x/sum(x)``. If ``sum(x) < 1``, then the values of *x* give
  2246. the fractional area directly and the array will not be normalized. The
  2247. resulting pie will have an empty wedge of size ``1 - sum(x)``.
  2248. The wedges are plotted counterclockwise, by default starting from the
  2249. x-axis.
  2250. Parameters
  2251. ----------
  2252. x : array-like
  2253. The wedge sizes.
  2254. explode : array-like, optional, default: None
  2255. If not *None*, is a ``len(x)`` array which specifies the fraction
  2256. of the radius with which to offset each wedge.
  2257. labels : list, optional, default: None
  2258. A sequence of strings providing the labels for each wedge
  2259. colors : array-like, optional, default: None
  2260. A sequence of matplotlib color args through which the pie chart
  2261. will cycle. If *None*, will use the colors in the currently
  2262. active cycle.
  2263. autopct : None (default), str, or function, optional
  2264. If not *None*, is a string or function used to label the wedges
  2265. with their numeric value. The label will be placed inside the
  2266. wedge. If it is a format string, the label will be ``fmt%pct``.
  2267. If it is a function, it will be called.
  2268. pctdistance : float, optional, default: 0.6
  2269. The ratio between the center of each pie slice and the start of
  2270. the text generated by *autopct*. Ignored if *autopct* is *None*.
  2271. shadow : bool, optional, default: False
  2272. Draw a shadow beneath the pie.
  2273. labeldistance : float or None, optional, default: 1.1
  2274. The radial distance at which the pie labels are drawn.
  2275. If set to ``None``, label are not drawn, but are stored for use in
  2276. ``legend()``
  2277. startangle : float, optional, default: None
  2278. If not *None*, rotates the start of the pie chart by *angle*
  2279. degrees counterclockwise from the x-axis.
  2280. radius : float, optional, default: None
  2281. The radius of the pie, if *radius* is *None* it will be set to 1.
  2282. counterclock : bool, optional, default: True
  2283. Specify fractions direction, clockwise or counterclockwise.
  2284. wedgeprops : dict, optional, default: None
  2285. Dict of arguments passed to the wedge objects making the pie.
  2286. For example, you can pass in ``wedgeprops = {'linewidth': 3}``
  2287. to set the width of the wedge border lines equal to 3.
  2288. For more details, look at the doc/arguments of the wedge object.
  2289. By default ``clip_on=False``.
  2290. textprops : dict, optional, default: None
  2291. Dict of arguments to pass to the text objects.
  2292. center : list of float, optional, default: (0, 0)
  2293. Center position of the chart. Takes value (0, 0) or is a sequence
  2294. of 2 scalars.
  2295. frame : bool, optional, default: False
  2296. Plot axes frame with the chart if true.
  2297. rotatelabels : bool, optional, default: False
  2298. Rotate each label to the angle of the corresponding slice if true.
  2299. Returns
  2300. -------
  2301. patches : list
  2302. A sequence of :class:`matplotlib.patches.Wedge` instances
  2303. texts : list
  2304. A list of the label :class:`matplotlib.text.Text` instances.
  2305. autotexts : list
  2306. A list of :class:`~matplotlib.text.Text` instances for the numeric
  2307. labels. This will only be returned if the parameter *autopct* is
  2308. not *None*.
  2309. Notes
  2310. -----
  2311. The pie chart will probably look best if the figure and axes are
  2312. square, or the Axes aspect is equal.
  2313. This method sets the aspect ratio of the axis to "equal".
  2314. The axes aspect ratio can be controlled with `Axes.set_aspect`.
  2315. """
  2316. self.set_aspect('equal')
  2317. # The use of float32 is "historical", but can't be changed without
  2318. # regenerating the test baselines.
  2319. x = np.asarray(x, np.float32)
  2320. if x.ndim != 1 and x.squeeze().ndim <= 1:
  2321. cbook.warn_deprecated(
  2322. "3.1", message="Non-1D inputs to pie() are currently "
  2323. "squeeze()d, but this behavior is deprecated since %(since)s "
  2324. "and will be removed %(removal)s; pass a 1D array instead.")
  2325. x = np.atleast_1d(x.squeeze())
  2326. sx = x.sum()
  2327. if sx > 1:
  2328. x = x / sx
  2329. if labels is None:
  2330. labels = [''] * len(x)
  2331. if explode is None:
  2332. explode = [0] * len(x)
  2333. if len(x) != len(labels):
  2334. raise ValueError("'label' must be of length 'x'")
  2335. if len(x) != len(explode):
  2336. raise ValueError("'explode' must be of length 'x'")
  2337. if colors is None:
  2338. get_next_color = self._get_patches_for_fill.get_next_color
  2339. else:
  2340. color_cycle = itertools.cycle(colors)
  2341. def get_next_color():
  2342. return next(color_cycle)
  2343. if radius is None:
  2344. radius = 1
  2345. # Starting theta1 is the start fraction of the circle
  2346. if startangle is None:
  2347. theta1 = 0
  2348. else:
  2349. theta1 = startangle / 360.0
  2350. # set default values in wedge_prop
  2351. if wedgeprops is None:
  2352. wedgeprops = {}
  2353. wedgeprops.setdefault('clip_on', False)
  2354. if textprops is None:
  2355. textprops = {}
  2356. textprops.setdefault('clip_on', False)
  2357. texts = []
  2358. slices = []
  2359. autotexts = []
  2360. for frac, label, expl in zip(x, labels, explode):
  2361. x, y = center
  2362. theta2 = (theta1 + frac) if counterclock else (theta1 - frac)
  2363. thetam = 2 * np.pi * 0.5 * (theta1 + theta2)
  2364. x += expl * math.cos(thetam)
  2365. y += expl * math.sin(thetam)
  2366. w = mpatches.Wedge((x, y), radius, 360. * min(theta1, theta2),
  2367. 360. * max(theta1, theta2),
  2368. facecolor=get_next_color(),
  2369. **wedgeprops)
  2370. slices.append(w)
  2371. self.add_patch(w)
  2372. w.set_label(label)
  2373. if shadow:
  2374. # make sure to add a shadow after the call to
  2375. # add_patch so the figure and transform props will be
  2376. # set
  2377. shad = mpatches.Shadow(w, -0.02, -0.02)
  2378. shad.set_zorder(0.9 * w.get_zorder())
  2379. shad.set_label('_nolegend_')
  2380. self.add_patch(shad)
  2381. if labeldistance is not None:
  2382. xt = x + labeldistance * radius * math.cos(thetam)
  2383. yt = y + labeldistance * radius * math.sin(thetam)
  2384. label_alignment_h = 'left' if xt > 0 else 'right'
  2385. label_alignment_v = 'center'
  2386. label_rotation = 'horizontal'
  2387. if rotatelabels:
  2388. label_alignment_v = 'bottom' if yt > 0 else 'top'
  2389. label_rotation = (np.rad2deg(thetam)
  2390. + (0 if xt > 0 else 180))
  2391. props = dict(horizontalalignment=label_alignment_h,
  2392. verticalalignment=label_alignment_v,
  2393. rotation=label_rotation,
  2394. size=rcParams['xtick.labelsize'])
  2395. props.update(textprops)
  2396. t = self.text(xt, yt, label, **props)
  2397. texts.append(t)
  2398. if autopct is not None:
  2399. xt = x + pctdistance * radius * math.cos(thetam)
  2400. yt = y + pctdistance * radius * math.sin(thetam)
  2401. if isinstance(autopct, str):
  2402. s = autopct % (100. * frac)
  2403. elif callable(autopct):
  2404. s = autopct(100. * frac)
  2405. else:
  2406. raise TypeError(
  2407. 'autopct must be callable or a format string')
  2408. props = dict(horizontalalignment='center',
  2409. verticalalignment='center')
  2410. props.update(textprops)
  2411. t = self.text(xt, yt, s, **props)
  2412. autotexts.append(t)
  2413. theta1 = theta2
  2414. if not frame:
  2415. self.set_frame_on(False)
  2416. self.set_xlim((-1.25 + center[0],
  2417. 1.25 + center[0]))
  2418. self.set_ylim((-1.25 + center[1],
  2419. 1.25 + center[1]))
  2420. self.set_xticks([])
  2421. self.set_yticks([])
  2422. if autopct is None:
  2423. return slices, texts
  2424. else:
  2425. return slices, texts, autotexts
  2426. @_preprocess_data(replace_names=["x", "y", "xerr", "yerr"],
  2427. label_namer="y")
  2428. @docstring.dedent_interpd
  2429. def errorbar(self, x, y, yerr=None, xerr=None,
  2430. fmt='', ecolor=None, elinewidth=None, capsize=None,
  2431. barsabove=False, lolims=False, uplims=False,
  2432. xlolims=False, xuplims=False, errorevery=1, capthick=None,
  2433. **kwargs):
  2434. """
  2435. Plot y versus x as lines and/or markers with attached errorbars.
  2436. *x*, *y* define the data locations, *xerr*, *yerr* define the errorbar
  2437. sizes. By default, this draws the data markers/lines as well the
  2438. errorbars. Use fmt='none' to draw errorbars without any data markers.
  2439. Parameters
  2440. ----------
  2441. x, y : scalar or array-like
  2442. The data positions.
  2443. xerr, yerr : scalar or array-like, shape(N,) or shape(2, N), optional
  2444. The errorbar sizes:
  2445. - scalar: Symmetric +/- values for all data points.
  2446. - shape(N,): Symmetric +/-values for each data point.
  2447. - shape(2, N): Separate - and + values for each bar. First row
  2448. contains the lower errors, the second row contains the upper
  2449. errors.
  2450. - *None*: No errorbar.
  2451. Note that all error arrays should have *positive* values.
  2452. See :doc:`/gallery/statistics/errorbar_features`
  2453. for an example on the usage of ``xerr`` and ``yerr``.
  2454. fmt : str, optional, default: ''
  2455. The format for the data points / data lines. See `.plot` for
  2456. details.
  2457. Use 'none' (case insensitive) to plot errorbars without any data
  2458. markers.
  2459. ecolor : color, optional, default: None
  2460. The color of the errorbar lines. If None, use the color of the
  2461. line connecting the markers.
  2462. elinewidth : scalar, optional, default: None
  2463. The linewidth of the errorbar lines. If None, the linewidth of
  2464. the current style is used.
  2465. capsize : scalar, optional, default: None
  2466. The length of the error bar caps in points. If None, it will take
  2467. the value from :rc:`errorbar.capsize`.
  2468. capthick : scalar, optional, default: None
  2469. An alias to the keyword argument *markeredgewidth* (a.k.a. *mew*).
  2470. This setting is a more sensible name for the property that
  2471. controls the thickness of the error bar cap in points. For
  2472. backwards compatibility, if *mew* or *markeredgewidth* are given,
  2473. then they will over-ride *capthick*. This may change in future
  2474. releases.
  2475. barsabove : bool, optional, default: False
  2476. If True, will plot the errorbars above the plot
  2477. symbols. Default is below.
  2478. lolims, uplims, xlolims, xuplims : bool, optional, default: False
  2479. These arguments can be used to indicate that a value gives only
  2480. upper/lower limits. In that case a caret symbol is used to
  2481. indicate this. *lims*-arguments may be of the same type as *xerr*
  2482. and *yerr*. To use limits with inverted axes, :meth:`set_xlim`
  2483. or :meth:`set_ylim` must be called before :meth:`errorbar`.
  2484. errorevery : int or (int, int), optional, default: 1
  2485. draws error bars on a subset of the data. *errorevery* =N draws
  2486. error bars on the points (x[::N], y[::N]).
  2487. *errorevery* =(start, N) draws error bars on the points
  2488. (x[start::N], y[start::N]). e.g. errorevery=(6, 3)
  2489. adds error bars to the data at (x[6], x[9], x[12], x[15], ...).
  2490. Used to avoid overlapping error bars when two series share x-axis
  2491. values.
  2492. Returns
  2493. -------
  2494. container : :class:`~.container.ErrorbarContainer`
  2495. The container contains:
  2496. - plotline: `.Line2D` instance of x, y plot markers and/or line.
  2497. - caplines: A tuple of `.Line2D` instances of the error bar caps.
  2498. - barlinecols: A tuple of
  2499. :class:`~matplotlib.collections.LineCollection` with the
  2500. horizontal and vertical error ranges.
  2501. Other Parameters
  2502. ----------------
  2503. **kwargs
  2504. All other keyword arguments are passed on to the plot
  2505. command for the markers. For example, this code makes big red
  2506. squares with thick green edges::
  2507. x, y, yerr = rand(3, 10)
  2508. errorbar(x, y, yerr, marker='s', mfc='red',
  2509. mec='green', ms=20, mew=4)
  2510. where *mfc*, *mec*, *ms* and *mew* are aliases for the longer
  2511. property names, *markerfacecolor*, *markeredgecolor*, *markersize*
  2512. and *markeredgewidth*.
  2513. Valid kwargs for the marker properties are `.Lines2D` properties:
  2514. %(_Line2D_docstr)s
  2515. """
  2516. kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)
  2517. # anything that comes in as 'None', drop so the default thing
  2518. # happens down stream
  2519. kwargs = {k: v for k, v in kwargs.items() if v is not None}
  2520. kwargs.setdefault('zorder', 2)
  2521. try:
  2522. offset, errorevery = errorevery
  2523. except TypeError:
  2524. offset = 0
  2525. if errorevery < 1 or int(errorevery) != errorevery:
  2526. raise ValueError(
  2527. 'errorevery must be positive integer or tuple of integers')
  2528. if int(offset) != offset:
  2529. raise ValueError("errorevery's starting index must be an integer")
  2530. self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs)
  2531. plot_line = (fmt.lower() != 'none')
  2532. label = kwargs.pop("label", None)
  2533. if fmt == '':
  2534. fmt_style_kwargs = {}
  2535. else:
  2536. fmt_style_kwargs = {k: v for k, v in
  2537. zip(('linestyle', 'marker', 'color'),
  2538. _process_plot_format(fmt))
  2539. if v is not None}
  2540. if fmt == 'none':
  2541. # Remove alpha=0 color that _process_plot_format returns
  2542. fmt_style_kwargs.pop('color')
  2543. if ('color' in kwargs or 'color' in fmt_style_kwargs or
  2544. ecolor is not None):
  2545. base_style = {}
  2546. if 'color' in kwargs:
  2547. base_style['color'] = kwargs.pop('color')
  2548. else:
  2549. base_style = next(self._get_lines.prop_cycler)
  2550. base_style['label'] = '_nolegend_'
  2551. base_style.update(fmt_style_kwargs)
  2552. if 'color' not in base_style:
  2553. base_style['color'] = 'C0'
  2554. if ecolor is None:
  2555. ecolor = base_style['color']
  2556. # make sure all the args are iterable; use lists not arrays to
  2557. # preserve units
  2558. if not np.iterable(x):
  2559. x = [x]
  2560. if not np.iterable(y):
  2561. y = [y]
  2562. if xerr is not None:
  2563. if not np.iterable(xerr):
  2564. xerr = [xerr] * len(x)
  2565. if yerr is not None:
  2566. if not np.iterable(yerr):
  2567. yerr = [yerr] * len(y)
  2568. # make the style dict for the 'normal' plot line
  2569. plot_line_style = {
  2570. **base_style,
  2571. **kwargs,
  2572. 'zorder': (kwargs['zorder'] - .1 if barsabove else
  2573. kwargs['zorder'] + .1),
  2574. }
  2575. # make the style dict for the line collections (the bars)
  2576. eb_lines_style = dict(base_style)
  2577. eb_lines_style.pop('marker', None)
  2578. eb_lines_style.pop('linestyle', None)
  2579. eb_lines_style['color'] = ecolor
  2580. if elinewidth:
  2581. eb_lines_style['linewidth'] = elinewidth
  2582. elif 'linewidth' in kwargs:
  2583. eb_lines_style['linewidth'] = kwargs['linewidth']
  2584. for key in ('transform', 'alpha', 'zorder', 'rasterized'):
  2585. if key in kwargs:
  2586. eb_lines_style[key] = kwargs[key]
  2587. # set up cap style dictionary
  2588. eb_cap_style = dict(base_style)
  2589. # eject any marker information from format string
  2590. eb_cap_style.pop('marker', None)
  2591. eb_lines_style.pop('markerfacecolor', None)
  2592. eb_lines_style.pop('markeredgewidth', None)
  2593. eb_lines_style.pop('markeredgecolor', None)
  2594. eb_cap_style.pop('ls', None)
  2595. eb_cap_style['linestyle'] = 'none'
  2596. if capsize is None:
  2597. capsize = rcParams["errorbar.capsize"]
  2598. if capsize > 0:
  2599. eb_cap_style['markersize'] = 2. * capsize
  2600. if capthick is not None:
  2601. eb_cap_style['markeredgewidth'] = capthick
  2602. # For backwards-compat, allow explicit setting of
  2603. # 'markeredgewidth' to over-ride capthick.
  2604. for key in ('markeredgewidth', 'transform', 'alpha',
  2605. 'zorder', 'rasterized'):
  2606. if key in kwargs:
  2607. eb_cap_style[key] = kwargs[key]
  2608. eb_cap_style['color'] = ecolor
  2609. data_line = None
  2610. if plot_line:
  2611. data_line = mlines.Line2D(x, y, **plot_line_style)
  2612. self.add_line(data_line)
  2613. barcols = []
  2614. caplines = []
  2615. # arrays fine here, they are booleans and hence not units
  2616. lolims = np.broadcast_to(lolims, len(x)).astype(bool)
  2617. uplims = np.broadcast_to(uplims, len(x)).astype(bool)
  2618. xlolims = np.broadcast_to(xlolims, len(x)).astype(bool)
  2619. xuplims = np.broadcast_to(xuplims, len(x)).astype(bool)
  2620. everymask = np.zeros(len(x), bool)
  2621. everymask[offset::errorevery] = True
  2622. def xywhere(xs, ys, mask):
  2623. """
  2624. return xs[mask], ys[mask] where mask is True but xs and
  2625. ys are not arrays
  2626. """
  2627. assert len(xs) == len(ys)
  2628. assert len(xs) == len(mask)
  2629. xs = [thisx for thisx, b in zip(xs, mask) if b]
  2630. ys = [thisy for thisy, b in zip(ys, mask) if b]
  2631. return xs, ys
  2632. def extract_err(err, data):
  2633. """
  2634. Private function to parse *err* and subtract/add it to *data*.
  2635. Both *err* and *data* are already iterables at this point.
  2636. """
  2637. try: # Asymmetric error: pair of 1D iterables.
  2638. a, b = err
  2639. iter(a)
  2640. iter(b)
  2641. except (TypeError, ValueError):
  2642. a = b = err # Symmetric error: 1D iterable.
  2643. # This could just be `np.ndim(a) > 1 and np.ndim(b) > 1`, except
  2644. # for the (undocumented, but tested) support for (n, 1) arrays.
  2645. a_sh = np.shape(a)
  2646. b_sh = np.shape(b)
  2647. if (len(a_sh) > 2 or (len(a_sh) == 2 and a_sh[1] != 1)
  2648. or len(b_sh) > 2 or (len(b_sh) == 2 and b_sh[1] != 1)):
  2649. raise ValueError(
  2650. "err must be a scalar or a 1D or (2, n) array-like")
  2651. if len(a_sh) == 2 or len(b_sh) == 2:
  2652. cbook.warn_deprecated(
  2653. "3.1", message="Support for passing a (n, 1)-shaped error "
  2654. "array to errorbar() is deprecated since Matplotlib "
  2655. "%(since)s and will be removed %(removal)s; pass a 1D "
  2656. "array instead.")
  2657. # Using list comprehensions rather than arrays to preserve units.
  2658. for e in [a, b]:
  2659. if len(data) != len(e):
  2660. raise ValueError(
  2661. f"The lengths of the data ({len(data)}) and the "
  2662. f"error {len(e)} do not match")
  2663. low = [v - e for v, e in zip(data, a)]
  2664. high = [v + e for v, e in zip(data, b)]
  2665. return low, high
  2666. if xerr is not None:
  2667. left, right = extract_err(xerr, x)
  2668. # select points without upper/lower limits in x and
  2669. # draw normal errorbars for these points
  2670. noxlims = ~(xlolims | xuplims)
  2671. if noxlims.any() or len(noxlims) == 0:
  2672. yo, _ = xywhere(y, right, noxlims & everymask)
  2673. lo, ro = xywhere(left, right, noxlims & everymask)
  2674. barcols.append(self.hlines(yo, lo, ro, **eb_lines_style))
  2675. if capsize > 0:
  2676. caplines.append(mlines.Line2D(lo, yo, marker='|',
  2677. **eb_cap_style))
  2678. caplines.append(mlines.Line2D(ro, yo, marker='|',
  2679. **eb_cap_style))
  2680. if xlolims.any():
  2681. yo, _ = xywhere(y, right, xlolims & everymask)
  2682. lo, ro = xywhere(x, right, xlolims & everymask)
  2683. barcols.append(self.hlines(yo, lo, ro, **eb_lines_style))
  2684. rightup, yup = xywhere(right, y, xlolims & everymask)
  2685. if self.xaxis_inverted():
  2686. marker = mlines.CARETLEFTBASE
  2687. else:
  2688. marker = mlines.CARETRIGHTBASE
  2689. caplines.append(
  2690. mlines.Line2D(rightup, yup, ls='None', marker=marker,
  2691. **eb_cap_style))
  2692. if capsize > 0:
  2693. xlo, ylo = xywhere(x, y, xlolims & everymask)
  2694. caplines.append(mlines.Line2D(xlo, ylo, marker='|',
  2695. **eb_cap_style))
  2696. if xuplims.any():
  2697. yo, _ = xywhere(y, right, xuplims & everymask)
  2698. lo, ro = xywhere(left, x, xuplims & everymask)
  2699. barcols.append(self.hlines(yo, lo, ro, **eb_lines_style))
  2700. leftlo, ylo = xywhere(left, y, xuplims & everymask)
  2701. if self.xaxis_inverted():
  2702. marker = mlines.CARETRIGHTBASE
  2703. else:
  2704. marker = mlines.CARETLEFTBASE
  2705. caplines.append(
  2706. mlines.Line2D(leftlo, ylo, ls='None', marker=marker,
  2707. **eb_cap_style))
  2708. if capsize > 0:
  2709. xup, yup = xywhere(x, y, xuplims & everymask)
  2710. caplines.append(mlines.Line2D(xup, yup, marker='|',
  2711. **eb_cap_style))
  2712. if yerr is not None:
  2713. lower, upper = extract_err(yerr, y)
  2714. # select points without upper/lower limits in y and
  2715. # draw normal errorbars for these points
  2716. noylims = ~(lolims | uplims)
  2717. if noylims.any() or len(noylims) == 0:
  2718. xo, _ = xywhere(x, lower, noylims & everymask)
  2719. lo, uo = xywhere(lower, upper, noylims & everymask)
  2720. barcols.append(self.vlines(xo, lo, uo, **eb_lines_style))
  2721. if capsize > 0:
  2722. caplines.append(mlines.Line2D(xo, lo, marker='_',
  2723. **eb_cap_style))
  2724. caplines.append(mlines.Line2D(xo, uo, marker='_',
  2725. **eb_cap_style))
  2726. if lolims.any():
  2727. xo, _ = xywhere(x, lower, lolims & everymask)
  2728. lo, uo = xywhere(y, upper, lolims & everymask)
  2729. barcols.append(self.vlines(xo, lo, uo, **eb_lines_style))
  2730. xup, upperup = xywhere(x, upper, lolims & everymask)
  2731. if self.yaxis_inverted():
  2732. marker = mlines.CARETDOWNBASE
  2733. else:
  2734. marker = mlines.CARETUPBASE
  2735. caplines.append(
  2736. mlines.Line2D(xup, upperup, ls='None', marker=marker,
  2737. **eb_cap_style))
  2738. if capsize > 0:
  2739. xlo, ylo = xywhere(x, y, lolims & everymask)
  2740. caplines.append(mlines.Line2D(xlo, ylo, marker='_',
  2741. **eb_cap_style))
  2742. if uplims.any():
  2743. xo, _ = xywhere(x, lower, uplims & everymask)
  2744. lo, uo = xywhere(lower, y, uplims & everymask)
  2745. barcols.append(self.vlines(xo, lo, uo, **eb_lines_style))
  2746. xlo, lowerlo = xywhere(x, lower, uplims & everymask)
  2747. if self.yaxis_inverted():
  2748. marker = mlines.CARETUPBASE
  2749. else:
  2750. marker = mlines.CARETDOWNBASE
  2751. caplines.append(
  2752. mlines.Line2D(xlo, lowerlo, ls='None', marker=marker,
  2753. **eb_cap_style))
  2754. if capsize > 0:
  2755. xup, yup = xywhere(x, y, uplims & everymask)
  2756. caplines.append(mlines.Line2D(xup, yup, marker='_',
  2757. **eb_cap_style))
  2758. for l in caplines:
  2759. self.add_line(l)
  2760. self._request_autoscale_view()
  2761. errorbar_container = ErrorbarContainer((data_line, tuple(caplines),
  2762. tuple(barcols)),
  2763. has_xerr=(xerr is not None),
  2764. has_yerr=(yerr is not None),
  2765. label=label)
  2766. self.containers.append(errorbar_container)
  2767. return errorbar_container # (l0, caplines, barcols)
  2768. @cbook._rename_parameter("3.1", "manage_xticks", "manage_ticks")
  2769. @_preprocess_data()
  2770. def boxplot(self, x, notch=None, sym=None, vert=None, whis=None,
  2771. positions=None, widths=None, patch_artist=None,
  2772. bootstrap=None, usermedians=None, conf_intervals=None,
  2773. meanline=None, showmeans=None, showcaps=None,
  2774. showbox=None, showfliers=None, boxprops=None,
  2775. labels=None, flierprops=None, medianprops=None,
  2776. meanprops=None, capprops=None, whiskerprops=None,
  2777. manage_ticks=True, autorange=False, zorder=None):
  2778. """
  2779. Make a box and whisker plot.
  2780. Make a box and whisker plot for each column of ``x`` or each
  2781. vector in sequence ``x``. The box extends from the lower to
  2782. upper quartile values of the data, with a line at the median.
  2783. The whiskers extend from the box to show the range of the
  2784. data. Flier points are those past the end of the whiskers.
  2785. Parameters
  2786. ----------
  2787. x : Array or a sequence of vectors.
  2788. The input data.
  2789. notch : bool, optional (False)
  2790. If `True`, will produce a notched box plot. Otherwise, a
  2791. rectangular boxplot is produced. The notches represent the
  2792. confidence interval (CI) around the median. See the entry
  2793. for the ``bootstrap`` parameter for information regarding
  2794. how the locations of the notches are computed.
  2795. .. note::
  2796. In cases where the values of the CI are less than the
  2797. lower quartile or greater than the upper quartile, the
  2798. notches will extend beyond the box, giving it a
  2799. distinctive "flipped" appearance. This is expected
  2800. behavior and consistent with other statistical
  2801. visualization packages.
  2802. sym : str, optional
  2803. The default symbol for flier points. Enter an empty string
  2804. ('') if you don't want to show fliers. If `None`, then the
  2805. fliers default to 'b+' If you want more control use the
  2806. flierprops kwarg.
  2807. vert : bool, optional (True)
  2808. If `True` (default), makes the boxes vertical. If `False`,
  2809. everything is drawn horizontally.
  2810. whis : float or (float, float) (default = 1.5)
  2811. The position of the whiskers.
  2812. If a float, the lower whisker is at the lowest datum above
  2813. ``Q1 - whis*(Q3-Q1)``, and the upper whisker at the highest datum
  2814. below ``Q3 + whis*(Q3-Q1)``, where Q1 and Q3 are the first and
  2815. third quartiles. The default value of ``whis = 1.5`` corresponds
  2816. to Tukey's original definition of boxplots.
  2817. If a pair of floats, they indicate the percentiles at which to
  2818. draw the whiskers (e.g., (5, 95)). In particular, setting this to
  2819. (0, 100) results in whiskers covering the whole range of the data.
  2820. "range" is a deprecated synonym for (0, 100).
  2821. In the edge case where ``Q1 == Q3``, *whis* is automatically set
  2822. to (0, 100) (cover the whole range of the data) if *autorange* is
  2823. True.
  2824. Beyond the whiskers, data are considered outliers and are plotted
  2825. as individual points.
  2826. bootstrap : int, optional
  2827. Specifies whether to bootstrap the confidence intervals
  2828. around the median for notched boxplots. If ``bootstrap`` is
  2829. None, no bootstrapping is performed, and notches are
  2830. calculated using a Gaussian-based asymptotic approximation
  2831. (see McGill, R., Tukey, J.W., and Larsen, W.A., 1978, and
  2832. Kendall and Stuart, 1967). Otherwise, bootstrap specifies
  2833. the number of times to bootstrap the median to determine its
  2834. 95% confidence intervals. Values between 1000 and 10000 are
  2835. recommended.
  2836. usermedians : array-like, optional
  2837. An array or sequence whose first dimension (or length) is
  2838. compatible with ``x``. This overrides the medians computed
  2839. by matplotlib for each element of ``usermedians`` that is not
  2840. `None`. When an element of ``usermedians`` is None, the median
  2841. will be computed by matplotlib as normal.
  2842. conf_intervals : array-like, optional
  2843. Array or sequence whose first dimension (or length) is
  2844. compatible with ``x`` and whose second dimension is 2. When
  2845. the an element of ``conf_intervals`` is not None, the
  2846. notch locations computed by matplotlib are overridden
  2847. (provided ``notch`` is `True`). When an element of
  2848. ``conf_intervals`` is `None`, the notches are computed by the
  2849. method specified by the other kwargs (e.g., ``bootstrap``).
  2850. positions : array-like, optional
  2851. Sets the positions of the boxes. The ticks and limits are
  2852. automatically set to match the positions. Defaults to
  2853. `range(1, N+1)` where N is the number of boxes to be drawn.
  2854. widths : scalar or array-like
  2855. Sets the width of each box either with a scalar or a
  2856. sequence. The default is 0.5, or ``0.15*(distance between
  2857. extreme positions)``, if that is smaller.
  2858. patch_artist : bool, optional (False)
  2859. If `False` produces boxes with the Line2D artist. Otherwise,
  2860. boxes and drawn with Patch artists.
  2861. labels : sequence, optional
  2862. Labels for each dataset. Length must be compatible with
  2863. dimensions of ``x``.
  2864. manage_ticks : bool, optional (True)
  2865. If True, the tick locations and labels will be adjusted to match
  2866. the boxplot positions.
  2867. autorange : bool, optional (False)
  2868. When `True` and the data are distributed such that the 25th and
  2869. 75th percentiles are equal, ``whis`` is set to (0, 100) such
  2870. that the whisker ends are at the minimum and maximum of the data.
  2871. meanline : bool, optional (False)
  2872. If `True` (and ``showmeans`` is `True`), will try to render
  2873. the mean as a line spanning the full width of the box
  2874. according to ``meanprops`` (see below). Not recommended if
  2875. ``shownotches`` is also True. Otherwise, means will be shown
  2876. as points.
  2877. zorder : scalar, optional (None)
  2878. Sets the zorder of the boxplot.
  2879. Other Parameters
  2880. ----------------
  2881. showcaps : bool, optional (True)
  2882. Show the caps on the ends of whiskers.
  2883. showbox : bool, optional (True)
  2884. Show the central box.
  2885. showfliers : bool, optional (True)
  2886. Show the outliers beyond the caps.
  2887. showmeans : bool, optional (False)
  2888. Show the arithmetic means.
  2889. capprops : dict, optional (None)
  2890. Specifies the style of the caps.
  2891. boxprops : dict, optional (None)
  2892. Specifies the style of the box.
  2893. whiskerprops : dict, optional (None)
  2894. Specifies the style of the whiskers.
  2895. flierprops : dict, optional (None)
  2896. Specifies the style of the fliers.
  2897. medianprops : dict, optional (None)
  2898. Specifies the style of the median.
  2899. meanprops : dict, optional (None)
  2900. Specifies the style of the mean.
  2901. Returns
  2902. -------
  2903. result : dict
  2904. A dictionary mapping each component of the boxplot to a list
  2905. of the `.Line2D` instances created. That dictionary has the
  2906. following keys (assuming vertical boxplots):
  2907. - ``boxes``: the main body of the boxplot showing the
  2908. quartiles and the median's confidence intervals if
  2909. enabled.
  2910. - ``medians``: horizontal lines at the median of each box.
  2911. - ``whiskers``: the vertical lines extending to the most
  2912. extreme, non-outlier data points.
  2913. - ``caps``: the horizontal lines at the ends of the
  2914. whiskers.
  2915. - ``fliers``: points representing data that extend beyond
  2916. the whiskers (fliers).
  2917. - ``means``: points or lines representing the means.
  2918. """
  2919. # Missing arguments default to rcParams.
  2920. if whis is None:
  2921. whis = rcParams['boxplot.whiskers']
  2922. if bootstrap is None:
  2923. bootstrap = rcParams['boxplot.bootstrap']
  2924. bxpstats = cbook.boxplot_stats(x, whis=whis, bootstrap=bootstrap,
  2925. labels=labels, autorange=autorange)
  2926. if notch is None:
  2927. notch = rcParams['boxplot.notch']
  2928. if vert is None:
  2929. vert = rcParams['boxplot.vertical']
  2930. if patch_artist is None:
  2931. patch_artist = rcParams['boxplot.patchartist']
  2932. if meanline is None:
  2933. meanline = rcParams['boxplot.meanline']
  2934. if showmeans is None:
  2935. showmeans = rcParams['boxplot.showmeans']
  2936. if showcaps is None:
  2937. showcaps = rcParams['boxplot.showcaps']
  2938. if showbox is None:
  2939. showbox = rcParams['boxplot.showbox']
  2940. if showfliers is None:
  2941. showfliers = rcParams['boxplot.showfliers']
  2942. if boxprops is None:
  2943. boxprops = {}
  2944. if whiskerprops is None:
  2945. whiskerprops = {}
  2946. if capprops is None:
  2947. capprops = {}
  2948. if medianprops is None:
  2949. medianprops = {}
  2950. if meanprops is None:
  2951. meanprops = {}
  2952. if flierprops is None:
  2953. flierprops = {}
  2954. if patch_artist:
  2955. boxprops['linestyle'] = 'solid' # Not consistent with bxp.
  2956. if 'color' in boxprops:
  2957. boxprops['edgecolor'] = boxprops.pop('color')
  2958. # if non-default sym value, put it into the flier dictionary
  2959. # the logic for providing the default symbol ('b+') now lives
  2960. # in bxp in the initial value of final_flierprops
  2961. # handle all of the *sym* related logic here so we only have to pass
  2962. # on the flierprops dict.
  2963. if sym is not None:
  2964. # no-flier case, which should really be done with
  2965. # 'showfliers=False' but none-the-less deal with it to keep back
  2966. # compatibility
  2967. if sym == '':
  2968. # blow away existing dict and make one for invisible markers
  2969. flierprops = dict(linestyle='none', marker='', color='none')
  2970. # turn the fliers off just to be safe
  2971. showfliers = False
  2972. # now process the symbol string
  2973. else:
  2974. # process the symbol string
  2975. # discarded linestyle
  2976. _, marker, color = _process_plot_format(sym)
  2977. # if we have a marker, use it
  2978. if marker is not None:
  2979. flierprops['marker'] = marker
  2980. # if we have a color, use it
  2981. if color is not None:
  2982. # assume that if color is passed in the user want
  2983. # filled symbol, if the users want more control use
  2984. # flierprops
  2985. flierprops['color'] = color
  2986. flierprops['markerfacecolor'] = color
  2987. flierprops['markeredgecolor'] = color
  2988. # replace medians if necessary:
  2989. if usermedians is not None:
  2990. if (len(np.ravel(usermedians)) != len(bxpstats) or
  2991. np.shape(usermedians)[0] != len(bxpstats)):
  2992. raise ValueError('usermedians length not compatible with x')
  2993. else:
  2994. # reassign medians as necessary
  2995. for stats, med in zip(bxpstats, usermedians):
  2996. if med is not None:
  2997. stats['med'] = med
  2998. if conf_intervals is not None:
  2999. if np.shape(conf_intervals)[0] != len(bxpstats):
  3000. err_mess = 'conf_intervals length not compatible with x'
  3001. raise ValueError(err_mess)
  3002. else:
  3003. for stats, ci in zip(bxpstats, conf_intervals):
  3004. if ci is not None:
  3005. if len(ci) != 2:
  3006. raise ValueError('each confidence interval must '
  3007. 'have two values')
  3008. else:
  3009. if ci[0] is not None:
  3010. stats['cilo'] = ci[0]
  3011. if ci[1] is not None:
  3012. stats['cihi'] = ci[1]
  3013. artists = self.bxp(bxpstats, positions=positions, widths=widths,
  3014. vert=vert, patch_artist=patch_artist,
  3015. shownotches=notch, showmeans=showmeans,
  3016. showcaps=showcaps, showbox=showbox,
  3017. boxprops=boxprops, flierprops=flierprops,
  3018. medianprops=medianprops, meanprops=meanprops,
  3019. meanline=meanline, showfliers=showfliers,
  3020. capprops=capprops, whiskerprops=whiskerprops,
  3021. manage_ticks=manage_ticks, zorder=zorder)
  3022. return artists
  3023. @cbook._rename_parameter("3.1", "manage_xticks", "manage_ticks")
  3024. def bxp(self, bxpstats, positions=None, widths=None, vert=True,
  3025. patch_artist=False, shownotches=False, showmeans=False,
  3026. showcaps=True, showbox=True, showfliers=True,
  3027. boxprops=None, whiskerprops=None, flierprops=None,
  3028. medianprops=None, capprops=None, meanprops=None,
  3029. meanline=False, manage_ticks=True, zorder=None):
  3030. """
  3031. Drawing function for box and whisker plots.
  3032. Make a box and whisker plot for each column of *x* or each
  3033. vector in sequence *x*. The box extends from the lower to
  3034. upper quartile values of the data, with a line at the median.
  3035. The whiskers extend from the box to show the range of the
  3036. data. Flier points are those past the end of the whiskers.
  3037. Parameters
  3038. ----------
  3039. bxpstats : list of dicts
  3040. A list of dictionaries containing stats for each boxplot.
  3041. Required keys are:
  3042. - ``med``: The median (scalar float).
  3043. - ``q1``: The first quartile (25th percentile) (scalar
  3044. float).
  3045. - ``q3``: The third quartile (75th percentile) (scalar
  3046. float).
  3047. - ``whislo``: Lower bound of the lower whisker (scalar
  3048. float).
  3049. - ``whishi``: Upper bound of the upper whisker (scalar
  3050. float).
  3051. Optional keys are:
  3052. - ``mean``: The mean (scalar float). Needed if
  3053. ``showmeans=True``.
  3054. - ``fliers``: Data beyond the whiskers (sequence of floats).
  3055. Needed if ``showfliers=True``.
  3056. - ``cilo`` & ``cihi``: Lower and upper confidence intervals
  3057. about the median. Needed if ``shownotches=True``.
  3058. - ``label``: Name of the dataset (string). If available,
  3059. this will be used a tick label for the boxplot
  3060. positions : array-like, default = [1, 2, ..., n]
  3061. Sets the positions of the boxes. The ticks and limits
  3062. are automatically set to match the positions.
  3063. widths : array-like, default = None
  3064. Either a scalar or a vector and sets the width of each
  3065. box. The default is ``0.15*(distance between extreme
  3066. positions)``, clipped to no less than 0.15 and no more than
  3067. 0.5.
  3068. vert : bool, default = True
  3069. If `True` (default), makes the boxes vertical. If `False`,
  3070. makes horizontal boxes.
  3071. patch_artist : bool, default = False
  3072. If `False` produces boxes with the `.Line2D` artist.
  3073. If `True` produces boxes with the `~matplotlib.patches.Patch` artist.
  3074. shownotches : bool, default = False
  3075. If `False` (default), produces a rectangular box plot.
  3076. If `True`, will produce a notched box plot
  3077. showmeans : bool, default = False
  3078. If `True`, will toggle on the rendering of the means
  3079. showcaps : bool, default = True
  3080. If `True`, will toggle on the rendering of the caps
  3081. showbox : bool, default = True
  3082. If `True`, will toggle on the rendering of the box
  3083. showfliers : bool, default = True
  3084. If `True`, will toggle on the rendering of the fliers
  3085. boxprops : dict or None (default)
  3086. If provided, will set the plotting style of the boxes
  3087. whiskerprops : dict or None (default)
  3088. If provided, will set the plotting style of the whiskers
  3089. capprops : dict or None (default)
  3090. If provided, will set the plotting style of the caps
  3091. flierprops : dict or None (default)
  3092. If provided will set the plotting style of the fliers
  3093. medianprops : dict or None (default)
  3094. If provided, will set the plotting style of the medians
  3095. meanprops : dict or None (default)
  3096. If provided, will set the plotting style of the means
  3097. meanline : bool, default = False
  3098. If `True` (and *showmeans* is `True`), will try to render the mean
  3099. as a line spanning the full width of the box according to
  3100. *meanprops*. Not recommended if *shownotches* is also True.
  3101. Otherwise, means will be shown as points.
  3102. manage_ticks : bool, default = True
  3103. If True, the tick locations and labels will be adjusted to match the
  3104. boxplot positions.
  3105. zorder : scalar, default = None
  3106. The zorder of the resulting boxplot.
  3107. Returns
  3108. -------
  3109. result : dict
  3110. A dictionary mapping each component of the boxplot to a list
  3111. of the `.Line2D` instances created. That dictionary has the
  3112. following keys (assuming vertical boxplots):
  3113. - ``boxes``: the main body of the boxplot showing the
  3114. quartiles and the median's confidence intervals if
  3115. enabled.
  3116. - ``medians``: horizontal lines at the median of each box.
  3117. - ``whiskers``: the vertical lines extending to the most
  3118. extreme, non-outlier data points.
  3119. - ``caps``: the horizontal lines at the ends of the
  3120. whiskers.
  3121. - ``fliers``: points representing data that extend beyond
  3122. the whiskers (fliers).
  3123. - ``means``: points or lines representing the means.
  3124. Examples
  3125. --------
  3126. .. plot:: gallery/statistics/bxp.py
  3127. """
  3128. # lists of artists to be output
  3129. whiskers = []
  3130. caps = []
  3131. boxes = []
  3132. medians = []
  3133. means = []
  3134. fliers = []
  3135. # empty list of xticklabels
  3136. datalabels = []
  3137. # Use default zorder if none specified
  3138. if zorder is None:
  3139. zorder = mlines.Line2D.zorder
  3140. zdelta = 0.1
  3141. def line_props_with_rcdefaults(subkey, explicit, zdelta=0):
  3142. d = {k.split('.')[-1]: v for k, v in rcParams.items()
  3143. if k.startswith(f'boxplot.{subkey}')}
  3144. d['zorder'] = zorder + zdelta
  3145. if explicit is not None:
  3146. d.update(
  3147. cbook.normalize_kwargs(explicit, mlines.Line2D._alias_map))
  3148. return d
  3149. # box properties
  3150. if patch_artist:
  3151. final_boxprops = dict(
  3152. linestyle=rcParams['boxplot.boxprops.linestyle'],
  3153. linewidth=rcParams['boxplot.boxprops.linewidth'],
  3154. edgecolor=rcParams['boxplot.boxprops.color'],
  3155. facecolor=('white' if rcParams['_internal.classic_mode'] else
  3156. rcParams['patch.facecolor']),
  3157. zorder=zorder,
  3158. )
  3159. if boxprops is not None:
  3160. final_boxprops.update(
  3161. cbook.normalize_kwargs(
  3162. boxprops, mpatches.PathPatch._alias_map))
  3163. else:
  3164. final_boxprops = line_props_with_rcdefaults('boxprops', boxprops)
  3165. final_whiskerprops = line_props_with_rcdefaults(
  3166. 'whiskerprops', whiskerprops)
  3167. final_capprops = line_props_with_rcdefaults(
  3168. 'capprops', capprops)
  3169. final_flierprops = line_props_with_rcdefaults(
  3170. 'flierprops', flierprops)
  3171. final_medianprops = line_props_with_rcdefaults(
  3172. 'medianprops', medianprops, zdelta)
  3173. final_meanprops = line_props_with_rcdefaults(
  3174. 'meanprops', meanprops, zdelta)
  3175. removed_prop = 'marker' if meanline else 'linestyle'
  3176. # Only remove the property if it's not set explicitly as a parameter.
  3177. if meanprops is None or removed_prop not in meanprops:
  3178. final_meanprops[removed_prop] = ''
  3179. def to_vc(xs, ys):
  3180. # convert arguments to verts and codes, append (0, 0) (ignored).
  3181. verts = np.append(np.column_stack([xs, ys]), [(0, 0)], 0)
  3182. codes = ([mpath.Path.MOVETO]
  3183. + [mpath.Path.LINETO] * (len(verts) - 2)
  3184. + [mpath.Path.CLOSEPOLY])
  3185. return verts, codes
  3186. def patch_list(xs, ys, **kwargs):
  3187. verts, codes = to_vc(xs, ys)
  3188. path = mpath.Path(verts, codes)
  3189. patch = mpatches.PathPatch(path, **kwargs)
  3190. self.add_artist(patch)
  3191. return [patch]
  3192. # vertical or horizontal plot?
  3193. if vert:
  3194. def doplot(*args, **kwargs):
  3195. return self.plot(*args, **kwargs)
  3196. def dopatch(xs, ys, **kwargs):
  3197. return patch_list(xs, ys, **kwargs)
  3198. else:
  3199. def doplot(*args, **kwargs):
  3200. shuffled = []
  3201. for i in range(0, len(args), 2):
  3202. shuffled.extend([args[i + 1], args[i]])
  3203. return self.plot(*shuffled, **kwargs)
  3204. def dopatch(xs, ys, **kwargs):
  3205. xs, ys = ys, xs # flip X, Y
  3206. return patch_list(xs, ys, **kwargs)
  3207. # input validation
  3208. N = len(bxpstats)
  3209. datashape_message = ("List of boxplot statistics and `{0}` "
  3210. "values must have same the length")
  3211. # check position
  3212. if positions is None:
  3213. positions = list(range(1, N + 1))
  3214. elif len(positions) != N:
  3215. raise ValueError(datashape_message.format("positions"))
  3216. positions = np.array(positions)
  3217. if len(positions) > 0 and not isinstance(positions[0], Number):
  3218. raise TypeError("positions should be an iterable of numbers")
  3219. # width
  3220. if widths is None:
  3221. widths = [np.clip(0.15 * np.ptp(positions), 0.15, 0.5)] * N
  3222. elif np.isscalar(widths):
  3223. widths = [widths] * N
  3224. elif len(widths) != N:
  3225. raise ValueError(datashape_message.format("widths"))
  3226. for pos, width, stats in zip(positions, widths, bxpstats):
  3227. # try to find a new label
  3228. datalabels.append(stats.get('label', pos))
  3229. # whisker coords
  3230. whisker_x = np.ones(2) * pos
  3231. whiskerlo_y = np.array([stats['q1'], stats['whislo']])
  3232. whiskerhi_y = np.array([stats['q3'], stats['whishi']])
  3233. # cap coords
  3234. cap_left = pos - width * 0.25
  3235. cap_right = pos + width * 0.25
  3236. cap_x = np.array([cap_left, cap_right])
  3237. cap_lo = np.ones(2) * stats['whislo']
  3238. cap_hi = np.ones(2) * stats['whishi']
  3239. # box and median coords
  3240. box_left = pos - width * 0.5
  3241. box_right = pos + width * 0.5
  3242. med_y = [stats['med'], stats['med']]
  3243. # notched boxes
  3244. if shownotches:
  3245. box_x = [box_left, box_right, box_right, cap_right, box_right,
  3246. box_right, box_left, box_left, cap_left, box_left,
  3247. box_left]
  3248. box_y = [stats['q1'], stats['q1'], stats['cilo'],
  3249. stats['med'], stats['cihi'], stats['q3'],
  3250. stats['q3'], stats['cihi'], stats['med'],
  3251. stats['cilo'], stats['q1']]
  3252. med_x = cap_x
  3253. # plain boxes
  3254. else:
  3255. box_x = [box_left, box_right, box_right, box_left, box_left]
  3256. box_y = [stats['q1'], stats['q1'], stats['q3'], stats['q3'],
  3257. stats['q1']]
  3258. med_x = [box_left, box_right]
  3259. # maybe draw the box:
  3260. if showbox:
  3261. if patch_artist:
  3262. boxes.extend(dopatch(box_x, box_y, **final_boxprops))
  3263. else:
  3264. boxes.extend(doplot(box_x, box_y, **final_boxprops))
  3265. # draw the whiskers
  3266. whiskers.extend(doplot(
  3267. whisker_x, whiskerlo_y, **final_whiskerprops
  3268. ))
  3269. whiskers.extend(doplot(
  3270. whisker_x, whiskerhi_y, **final_whiskerprops
  3271. ))
  3272. # maybe draw the caps:
  3273. if showcaps:
  3274. caps.extend(doplot(cap_x, cap_lo, **final_capprops))
  3275. caps.extend(doplot(cap_x, cap_hi, **final_capprops))
  3276. # draw the medians
  3277. medians.extend(doplot(med_x, med_y, **final_medianprops))
  3278. # maybe draw the means
  3279. if showmeans:
  3280. if meanline:
  3281. means.extend(doplot(
  3282. [box_left, box_right], [stats['mean'], stats['mean']],
  3283. **final_meanprops
  3284. ))
  3285. else:
  3286. means.extend(doplot(
  3287. [pos], [stats['mean']], **final_meanprops
  3288. ))
  3289. # maybe draw the fliers
  3290. if showfliers:
  3291. # fliers coords
  3292. flier_x = np.full(len(stats['fliers']), pos, dtype=np.float64)
  3293. flier_y = stats['fliers']
  3294. fliers.extend(doplot(
  3295. flier_x, flier_y, **final_flierprops
  3296. ))
  3297. if manage_ticks:
  3298. axis_name = "x" if vert else "y"
  3299. interval = getattr(self.dataLim, f"interval{axis_name}")
  3300. axis = getattr(self, f"{axis_name}axis")
  3301. positions = axis.convert_units(positions)
  3302. # The 0.5 additional padding ensures reasonable-looking boxes
  3303. # even when drawing a single box. We set the sticky edge to
  3304. # prevent margins expansion, in order to match old behavior (back
  3305. # when separate calls to boxplot() would completely reset the axis
  3306. # limits regardless of what was drawn before). The sticky edges
  3307. # are attached to the median lines, as they are always present.
  3308. interval[:] = (min(interval[0], min(positions) - .5),
  3309. max(interval[1], max(positions) + .5))
  3310. for median, position in zip(medians, positions):
  3311. getattr(median.sticky_edges, axis_name).extend(
  3312. [position - .5, position + .5])
  3313. # Modified from Axis.set_ticks and Axis.set_ticklabels.
  3314. locator = axis.get_major_locator()
  3315. if not isinstance(axis.get_major_locator(),
  3316. mticker.FixedLocator):
  3317. locator = mticker.FixedLocator([])
  3318. axis.set_major_locator(locator)
  3319. locator.locs = np.array([*locator.locs, *positions])
  3320. formatter = axis.get_major_formatter()
  3321. if not isinstance(axis.get_major_formatter(),
  3322. mticker.FixedFormatter):
  3323. formatter = mticker.FixedFormatter([])
  3324. axis.set_major_formatter(formatter)
  3325. formatter.seq = [*formatter.seq, *datalabels]
  3326. self._request_autoscale_view(
  3327. scalex=self._autoscaleXon, scaley=self._autoscaleYon)
  3328. return dict(whiskers=whiskers, caps=caps, boxes=boxes,
  3329. medians=medians, fliers=fliers, means=means)
  3330. @staticmethod
  3331. def _parse_scatter_color_args(c, edgecolors, kwargs, xsize,
  3332. get_next_color_func):
  3333. """
  3334. Helper function to process color related arguments of `.Axes.scatter`.
  3335. Argument precedence for facecolors:
  3336. - c (if not None)
  3337. - kwargs['facecolors']
  3338. - kwargs['facecolor']
  3339. - kwargs['color'] (==kwcolor)
  3340. - 'b' if in classic mode else the result of ``get_next_color_func()``
  3341. Argument precedence for edgecolors:
  3342. - edgecolors (is an explicit kw argument in scatter())
  3343. - kwargs['edgecolor']
  3344. - kwargs['color'] (==kwcolor)
  3345. - 'face' if not in classic mode else None
  3346. Parameters
  3347. ----------
  3348. c : color or sequence or sequence of color or None
  3349. See argument description of `.Axes.scatter`.
  3350. edgecolors : color or sequence of color or {'face', 'none'} or None
  3351. See argument description of `.Axes.scatter`.
  3352. kwargs : dict
  3353. Additional kwargs. If these keys exist, we pop and process them:
  3354. 'facecolors', 'facecolor', 'edgecolor', 'color'
  3355. Note: The dict is modified by this function.
  3356. xsize : int
  3357. The size of the x and y arrays passed to `.Axes.scatter`.
  3358. get_next_color_func : callable
  3359. A callable that returns a color. This color is used as facecolor
  3360. if no other color is provided.
  3361. Note, that this is a function rather than a fixed color value to
  3362. support conditional evaluation of the next color. As of the
  3363. current implementation obtaining the next color from the
  3364. property cycle advances the cycle. This must only happen if we
  3365. actually use the color, which will only be decided within this
  3366. method.
  3367. Returns
  3368. -------
  3369. c
  3370. The input *c* if it was not *None*, else a color derived from the
  3371. other inputs or defaults.
  3372. colors : array(N, 4) or None
  3373. The facecolors as RGBA values, or *None* if a colormap is used.
  3374. edgecolors
  3375. The edgecolor.
  3376. """
  3377. facecolors = kwargs.pop('facecolors', None)
  3378. facecolors = kwargs.pop('facecolor', facecolors)
  3379. edgecolors = kwargs.pop('edgecolor', edgecolors)
  3380. kwcolor = kwargs.pop('color', None)
  3381. if kwcolor is not None and c is not None:
  3382. raise ValueError("Supply a 'c' argument or a 'color'"
  3383. " kwarg but not both; they differ but"
  3384. " their functionalities overlap.")
  3385. if kwcolor is not None:
  3386. try:
  3387. mcolors.to_rgba_array(kwcolor)
  3388. except ValueError:
  3389. raise ValueError(
  3390. "'color' kwarg must be an color or sequence of color "
  3391. "specs. For a sequence of values to be color-mapped, use "
  3392. "the 'c' argument instead.")
  3393. if edgecolors is None:
  3394. edgecolors = kwcolor
  3395. if facecolors is None:
  3396. facecolors = kwcolor
  3397. if edgecolors is None and not rcParams['_internal.classic_mode']:
  3398. edgecolors = rcParams['scatter.edgecolors']
  3399. c_was_none = c is None
  3400. if c is None:
  3401. c = (facecolors if facecolors is not None
  3402. else "b" if rcParams['_internal.classic_mode']
  3403. else get_next_color_func())
  3404. c_is_string_or_strings = (
  3405. isinstance(c, str)
  3406. or (isinstance(c, collections.abc.Iterable) and len(c) > 0
  3407. and isinstance(cbook.safe_first_element(c), str)))
  3408. def invalid_shape_exception(csize, xsize):
  3409. return ValueError(
  3410. f"'c' argument has {csize} elements, which is inconsistent "
  3411. f"with 'x' and 'y' with size {xsize}.")
  3412. c_is_mapped = False # Unless proven otherwise below.
  3413. valid_shape = True # Unless proven otherwise below.
  3414. if not c_was_none and kwcolor is None and not c_is_string_or_strings:
  3415. try: # First, does 'c' look suitable for value-mapping?
  3416. c = np.asanyarray(c, dtype=float)
  3417. except ValueError:
  3418. pass # Failed to convert to float array; must be color specs.
  3419. else:
  3420. # If c can be either mapped values or a RGB(A) color, prefer
  3421. # the former if shapes match, the latter otherwise.
  3422. if c.size == xsize:
  3423. c = c.ravel()
  3424. c_is_mapped = True
  3425. else: # Wrong size; it must not be intended for mapping.
  3426. if c.shape in ((3,), (4,)):
  3427. _log.warning(
  3428. "'c' argument looks like a single numeric RGB or "
  3429. "RGBA sequence, which should be avoided as value-"
  3430. "mapping will have precedence in case its length "
  3431. "matches with 'x' & 'y'. Please use a 2-D array "
  3432. "with a single row if you really want to specify "
  3433. "the same RGB or RGBA value for all points.")
  3434. valid_shape = False
  3435. if not c_is_mapped:
  3436. try: # Is 'c' acceptable as PathCollection facecolors?
  3437. colors = mcolors.to_rgba_array(c)
  3438. except ValueError:
  3439. if not valid_shape:
  3440. raise invalid_shape_exception(c.size, xsize)
  3441. # Both the mapping *and* the RGBA conversion failed: pretty
  3442. # severe failure => one may appreciate a verbose feedback.
  3443. raise ValueError(
  3444. f"'c' argument must be a color, a sequence of colors, or "
  3445. f"a sequence of numbers, not {c}")
  3446. else:
  3447. if len(colors) not in (0, 1, xsize):
  3448. # NB: remember that a single color is also acceptable.
  3449. # Besides *colors* will be an empty array if c == 'none'.
  3450. raise invalid_shape_exception(len(colors), xsize)
  3451. else:
  3452. colors = None # use cmap, norm after collection is created
  3453. return c, colors, edgecolors
  3454. @_preprocess_data(replace_names=["x", "y", "s", "linewidths",
  3455. "edgecolors", "c", "facecolor",
  3456. "facecolors", "color"],
  3457. label_namer="y")
  3458. @cbook._delete_parameter("3.2", "verts")
  3459. def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
  3460. vmin=None, vmax=None, alpha=None, linewidths=None,
  3461. verts=None, edgecolors=None, *, plotnonfinite=False,
  3462. **kwargs):
  3463. """
  3464. A scatter plot of *y* vs. *x* with varying marker size and/or color.
  3465. Parameters
  3466. ----------
  3467. x, y : scalar or array-like, shape (n, )
  3468. The data positions.
  3469. s : scalar or array-like, shape (n, ), optional
  3470. The marker size in points**2.
  3471. Default is ``rcParams['lines.markersize'] ** 2``.
  3472. c : color, sequence, or sequence of colors, optional
  3473. The marker color. Possible values:
  3474. - A single color format string.
  3475. - A sequence of colors of length n.
  3476. - A scalar or sequence of n numbers to be mapped to colors using
  3477. *cmap* and *norm*.
  3478. - A 2-D array in which the rows are RGB or RGBA.
  3479. Note that *c* should not be a single numeric RGB or RGBA sequence
  3480. because that is indistinguishable from an array of values to be
  3481. colormapped. If you want to specify the same RGB or RGBA value for
  3482. all points, use a 2-D array with a single row. Otherwise, value-
  3483. matching will have precedence in case of a size matching with *x*
  3484. and *y*.
  3485. Defaults to ``None``. In that case the marker color is determined
  3486. by the value of ``color``, ``facecolor`` or ``facecolors``. In case
  3487. those are not specified or ``None``, the marker color is determined
  3488. by the next color of the ``Axes``' current "shape and fill" color
  3489. cycle. This cycle defaults to :rc:`axes.prop_cycle`.
  3490. marker : `~matplotlib.markers.MarkerStyle`, optional
  3491. The marker style. *marker* can be either an instance of the class
  3492. or the text shorthand for a particular marker.
  3493. Defaults to ``None``, in which case it takes the value of
  3494. :rc:`scatter.marker` = 'o'.
  3495. See `~matplotlib.markers` for more information about marker styles.
  3496. cmap : `~matplotlib.colors.Colormap`, optional, default: None
  3497. A `.Colormap` instance or registered colormap name. *cmap* is only
  3498. used if *c* is an array of floats. If ``None``, defaults to rc
  3499. ``image.cmap``.
  3500. norm : `~matplotlib.colors.Normalize`, optional, default: None
  3501. A `.Normalize` instance is used to scale luminance data to 0, 1.
  3502. *norm* is only used if *c* is an array of floats. If *None*, use
  3503. the default `.colors.Normalize`.
  3504. vmin, vmax : scalar, optional, default: None
  3505. *vmin* and *vmax* are used in conjunction with *norm* to normalize
  3506. luminance data. If None, the respective min and max of the color
  3507. array is used. *vmin* and *vmax* are ignored if you pass a *norm*
  3508. instance.
  3509. alpha : scalar, optional, default: None
  3510. The alpha blending value, between 0 (transparent) and 1 (opaque).
  3511. linewidths : scalar or array-like, optional, default: None
  3512. The linewidth of the marker edges. Note: The default *edgecolors*
  3513. is 'face'. You may want to change this as well.
  3514. If *None*, defaults to :rc:`lines.linewidth`.
  3515. edgecolors : {'face', 'none', *None*} or color or sequence of color, \
  3516. optional.
  3517. The edge color of the marker. Possible values:
  3518. - 'face': The edge color will always be the same as the face color.
  3519. - 'none': No patch boundary will be drawn.
  3520. - A Matplotlib color or sequence of color.
  3521. Defaults to ``None``, in which case it takes the value of
  3522. :rc:`scatter.edgecolors` = 'face'.
  3523. For non-filled markers, the *edgecolors* kwarg is ignored and
  3524. forced to 'face' internally.
  3525. plotnonfinite : boolean, optional, default: False
  3526. Set to plot points with nonfinite *c*, in conjunction with
  3527. `~matplotlib.colors.Colormap.set_bad`.
  3528. Returns
  3529. -------
  3530. paths : `~matplotlib.collections.PathCollection`
  3531. Other Parameters
  3532. ----------------
  3533. **kwargs : `~matplotlib.collections.Collection` properties
  3534. See Also
  3535. --------
  3536. plot : To plot scatter plots when markers are identical in size and
  3537. color.
  3538. Notes
  3539. -----
  3540. * The `.plot` function will be faster for scatterplots where markers
  3541. don't vary in size or color.
  3542. * Any or all of *x*, *y*, *s*, and *c* may be masked arrays, in which
  3543. case all masks will be combined and only unmasked points will be
  3544. plotted.
  3545. * Fundamentally, scatter works with 1-D arrays; *x*, *y*, *s*, and *c*
  3546. may be input as N-D arrays, but within scatter they will be
  3547. flattened. The exception is *c*, which will be flattened only if its
  3548. size matches the size of *x* and *y*.
  3549. """
  3550. # Process **kwargs to handle aliases, conflicts with explicit kwargs:
  3551. self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs)
  3552. x = self.convert_xunits(x)
  3553. y = self.convert_yunits(y)
  3554. # np.ma.ravel yields an ndarray, not a masked array,
  3555. # unless its argument is a masked array.
  3556. x = np.ma.ravel(x)
  3557. y = np.ma.ravel(y)
  3558. if x.size != y.size:
  3559. raise ValueError("x and y must be the same size")
  3560. if s is None:
  3561. s = (20 if rcParams['_internal.classic_mode'] else
  3562. rcParams['lines.markersize'] ** 2.0)
  3563. s = np.ma.ravel(s)
  3564. if len(s) not in (1, x.size):
  3565. raise ValueError("s must be a scalar, or the same size as x and y")
  3566. c, colors, edgecolors = \
  3567. self._parse_scatter_color_args(
  3568. c, edgecolors, kwargs, x.size,
  3569. get_next_color_func=self._get_patches_for_fill.get_next_color)
  3570. if plotnonfinite and colors is None:
  3571. c = np.ma.masked_invalid(c)
  3572. x, y, s, edgecolors, linewidths = \
  3573. cbook._combine_masks(x, y, s, edgecolors, linewidths)
  3574. else:
  3575. x, y, s, c, colors, edgecolors, linewidths = \
  3576. cbook._combine_masks(
  3577. x, y, s, c, colors, edgecolors, linewidths)
  3578. scales = s # Renamed for readability below.
  3579. # load default marker from rcParams
  3580. if marker is None:
  3581. marker = rcParams['scatter.marker']
  3582. if isinstance(marker, mmarkers.MarkerStyle):
  3583. marker_obj = marker
  3584. else:
  3585. marker_obj = mmarkers.MarkerStyle(marker)
  3586. path = marker_obj.get_path().transformed(
  3587. marker_obj.get_transform())
  3588. if not marker_obj.is_filled():
  3589. edgecolors = 'face'
  3590. linewidths = rcParams['lines.linewidth']
  3591. offsets = np.ma.column_stack([x, y])
  3592. collection = mcoll.PathCollection(
  3593. (path,), scales,
  3594. facecolors=colors,
  3595. edgecolors=edgecolors,
  3596. linewidths=linewidths,
  3597. offsets=offsets,
  3598. transOffset=kwargs.pop('transform', self.transData),
  3599. alpha=alpha
  3600. )
  3601. collection.set_transform(mtransforms.IdentityTransform())
  3602. collection.update(kwargs)
  3603. if colors is None:
  3604. collection.set_array(c)
  3605. collection.set_cmap(cmap)
  3606. collection.set_norm(norm)
  3607. if vmin is not None or vmax is not None:
  3608. collection.set_clim(vmin, vmax)
  3609. else:
  3610. collection.autoscale_None()
  3611. # Classic mode only:
  3612. # ensure there are margins to allow for the
  3613. # finite size of the symbols. In v2.x, margins
  3614. # are present by default, so we disable this
  3615. # scatter-specific override.
  3616. if rcParams['_internal.classic_mode']:
  3617. if self._xmargin < 0.05 and x.size > 0:
  3618. self.set_xmargin(0.05)
  3619. if self._ymargin < 0.05 and x.size > 0:
  3620. self.set_ymargin(0.05)
  3621. self.add_collection(collection)
  3622. self._request_autoscale_view()
  3623. return collection
  3624. @_preprocess_data(replace_names=["x", "y"], label_namer="y")
  3625. @docstring.dedent_interpd
  3626. def hexbin(self, x, y, C=None, gridsize=100, bins=None,
  3627. xscale='linear', yscale='linear', extent=None,
  3628. cmap=None, norm=None, vmin=None, vmax=None,
  3629. alpha=None, linewidths=None, edgecolors='face',
  3630. reduce_C_function=np.mean, mincnt=None, marginals=False,
  3631. **kwargs):
  3632. """
  3633. Make a 2D hexagonal binning plot of points *x*, *y*.
  3634. If *C* is *None*, the value of the hexagon is determined by the number
  3635. of points in the hexagon. Otherwise, *C* specifies values at the
  3636. coordinate (x[i], y[i]). For each hexagon, these values are reduced
  3637. using *reduce_C_function*.
  3638. Parameters
  3639. ----------
  3640. x, y : array-like
  3641. The data positions. *x* and *y* must be of the same length.
  3642. C : array-like, optional
  3643. If given, these values are accumulated in the bins. Otherwise,
  3644. every point has a value of 1. Must be of the same length as *x*
  3645. and *y*.
  3646. gridsize : int or (int, int), default: 100
  3647. If a single int, the number of hexagons in the *x*-direction.
  3648. The number of hexagons in the *y*-direction is chosen such that
  3649. the hexagons are approximately regular.
  3650. Alternatively, if a tuple (*nx*, *ny*), the number of hexagons
  3651. in the *x*-direction and the *y*-direction.
  3652. bins : 'log' or int or sequence, default: *None*
  3653. Discretization of the hexagon values.
  3654. - If *None*, no binning is applied; the color of each hexagon
  3655. directly corresponds to its count value.
  3656. - If 'log', use a logarithmic scale for the color map.
  3657. Internally, :math:`log_{10}(i+1)` is used to determine the
  3658. hexagon color. This is equivalent to ``norm=LogNorm()``.
  3659. - If an integer, divide the counts in the specified number
  3660. of bins, and color the hexagons accordingly.
  3661. - If a sequence of values, the values of the lower bound of
  3662. the bins to be used.
  3663. xscale : {'linear', 'log'}, default: 'linear'
  3664. Use a linear or log10 scale on the horizontal axis.
  3665. yscale : {'linear', 'log'}, default: 'linear'
  3666. Use a linear or log10 scale on the vertical axis.
  3667. mincnt : int > 0, default: *None*
  3668. If not *None*, only display cells with more than *mincnt*
  3669. number of points in the cell.
  3670. marginals : bool, default: *False*
  3671. If marginals is *True*, plot the marginal density as
  3672. colormapped rectangles along the bottom of the x-axis and
  3673. left of the y-axis.
  3674. extent : float, default: *None*
  3675. The limits of the bins. The default assigns the limits
  3676. based on *gridsize*, *x*, *y*, *xscale* and *yscale*.
  3677. If *xscale* or *yscale* is set to 'log', the limits are
  3678. expected to be the exponent for a power of 10. E.g. for
  3679. x-limits of 1 and 50 in 'linear' scale and y-limits
  3680. of 10 and 1000 in 'log' scale, enter (1, 50, 1, 3).
  3681. Order of scalars is (left, right, bottom, top).
  3682. Other Parameters
  3683. ----------------
  3684. cmap : str or `~matplotlib.colors.Colormap`, optional
  3685. The Colormap instance or registered colormap name used to map
  3686. the bin values to colors. Defaults to :rc:`image.cmap`.
  3687. norm : `~matplotlib.colors.Normalize`, optional
  3688. The Normalize instance scales the bin values to the canonical
  3689. colormap range [0, 1] for mapping to colors. By default, the data
  3690. range is mapped to the colorbar range using linear scaling.
  3691. vmin, vmax : float, optional, default: None
  3692. The colorbar range. If *None*, suitable min/max values are
  3693. automatically chosen by the `~.Normalize` instance (defaults to
  3694. the respective min/max values of the bins in case of the default
  3695. linear scaling). This is ignored if *norm* is given.
  3696. alpha : float between 0 and 1, optional
  3697. The alpha blending value, between 0 (transparent) and 1 (opaque).
  3698. linewidths : float, default: *None*
  3699. If *None*, defaults to 1.0.
  3700. edgecolors : {'face', 'none', *None*} or color, default: 'face'
  3701. The color of the hexagon edges. Possible values are:
  3702. - 'face': Draw the edges in the same color as the fill color.
  3703. - 'none': No edges are drawn. This can sometimes lead to unsightly
  3704. unpainted pixels between the hexagons.
  3705. - *None*: Draw outlines in the default color.
  3706. - An explicit matplotlib color.
  3707. reduce_C_function : callable, default is `numpy.mean`
  3708. The function to aggregate *C* within the bins. It is ignored if
  3709. *C* is not given. This must have the signature::
  3710. def reduce_C_function(C: array) -> float
  3711. Commonly used functions are:
  3712. - `numpy.mean`: average of the points
  3713. - `numpy.sum`: integral of the point values
  3714. - `numpy.max`: value taken from the largest point
  3715. **kwargs : `~matplotlib.collections.PolyCollection` properties
  3716. All other keyword arguments are passed on to `.PolyCollection`:
  3717. %(PolyCollection)s
  3718. Returns
  3719. -------
  3720. polycollection : `~matplotlib.collections.PolyCollection`
  3721. A `.PolyCollection` defining the hexagonal bins.
  3722. - `.PolyCollection.get_offset` contains a Mx2 array containing
  3723. the x, y positions of the M hexagon centers.
  3724. - `.PolyCollection.get_array` contains the values of the M
  3725. hexagons.
  3726. If *marginals* is *True*, horizontal
  3727. bar and vertical bar (both PolyCollections) will be attached
  3728. to the return collection as attributes *hbar* and *vbar*.
  3729. """
  3730. self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs)
  3731. x, y, C = cbook.delete_masked_points(x, y, C)
  3732. # Set the size of the hexagon grid
  3733. if np.iterable(gridsize):
  3734. nx, ny = gridsize
  3735. else:
  3736. nx = gridsize
  3737. ny = int(nx / math.sqrt(3))
  3738. # Count the number of data in each hexagon
  3739. x = np.array(x, float)
  3740. y = np.array(y, float)
  3741. if xscale == 'log':
  3742. if np.any(x <= 0.0):
  3743. raise ValueError("x contains non-positive values, so can not"
  3744. " be log-scaled")
  3745. x = np.log10(x)
  3746. if yscale == 'log':
  3747. if np.any(y <= 0.0):
  3748. raise ValueError("y contains non-positive values, so can not"
  3749. " be log-scaled")
  3750. y = np.log10(y)
  3751. if extent is not None:
  3752. xmin, xmax, ymin, ymax = extent
  3753. else:
  3754. xmin, xmax = (np.min(x), np.max(x)) if len(x) else (0, 1)
  3755. ymin, ymax = (np.min(y), np.max(y)) if len(y) else (0, 1)
  3756. # to avoid issues with singular data, expand the min/max pairs
  3757. xmin, xmax = mtransforms.nonsingular(xmin, xmax, expander=0.1)
  3758. ymin, ymax = mtransforms.nonsingular(ymin, ymax, expander=0.1)
  3759. # In the x-direction, the hexagons exactly cover the region from
  3760. # xmin to xmax. Need some padding to avoid roundoff errors.
  3761. padding = 1.e-9 * (xmax - xmin)
  3762. xmin -= padding
  3763. xmax += padding
  3764. sx = (xmax - xmin) / nx
  3765. sy = (ymax - ymin) / ny
  3766. if marginals:
  3767. xorig = x.copy()
  3768. yorig = y.copy()
  3769. x = (x - xmin) / sx
  3770. y = (y - ymin) / sy
  3771. ix1 = np.round(x).astype(int)
  3772. iy1 = np.round(y).astype(int)
  3773. ix2 = np.floor(x).astype(int)
  3774. iy2 = np.floor(y).astype(int)
  3775. nx1 = nx + 1
  3776. ny1 = ny + 1
  3777. nx2 = nx
  3778. ny2 = ny
  3779. n = nx1 * ny1 + nx2 * ny2
  3780. d1 = (x - ix1) ** 2 + 3.0 * (y - iy1) ** 2
  3781. d2 = (x - ix2 - 0.5) ** 2 + 3.0 * (y - iy2 - 0.5) ** 2
  3782. bdist = (d1 < d2)
  3783. if C is None:
  3784. lattice1 = np.zeros((nx1, ny1))
  3785. lattice2 = np.zeros((nx2, ny2))
  3786. c1 = (0 <= ix1) & (ix1 < nx1) & (0 <= iy1) & (iy1 < ny1) & bdist
  3787. c2 = (0 <= ix2) & (ix2 < nx2) & (0 <= iy2) & (iy2 < ny2) & ~bdist
  3788. np.add.at(lattice1, (ix1[c1], iy1[c1]), 1)
  3789. np.add.at(lattice2, (ix2[c2], iy2[c2]), 1)
  3790. if mincnt is not None:
  3791. lattice1[lattice1 < mincnt] = np.nan
  3792. lattice2[lattice2 < mincnt] = np.nan
  3793. accum = np.concatenate([lattice1.ravel(), lattice2.ravel()])
  3794. good_idxs = ~np.isnan(accum)
  3795. else:
  3796. if mincnt is None:
  3797. mincnt = 0
  3798. # create accumulation arrays
  3799. lattice1 = np.empty((nx1, ny1), dtype=object)
  3800. for i in range(nx1):
  3801. for j in range(ny1):
  3802. lattice1[i, j] = []
  3803. lattice2 = np.empty((nx2, ny2), dtype=object)
  3804. for i in range(nx2):
  3805. for j in range(ny2):
  3806. lattice2[i, j] = []
  3807. for i in range(len(x)):
  3808. if bdist[i]:
  3809. if 0 <= ix1[i] < nx1 and 0 <= iy1[i] < ny1:
  3810. lattice1[ix1[i], iy1[i]].append(C[i])
  3811. else:
  3812. if 0 <= ix2[i] < nx2 and 0 <= iy2[i] < ny2:
  3813. lattice2[ix2[i], iy2[i]].append(C[i])
  3814. for i in range(nx1):
  3815. for j in range(ny1):
  3816. vals = lattice1[i, j]
  3817. if len(vals) > mincnt:
  3818. lattice1[i, j] = reduce_C_function(vals)
  3819. else:
  3820. lattice1[i, j] = np.nan
  3821. for i in range(nx2):
  3822. for j in range(ny2):
  3823. vals = lattice2[i, j]
  3824. if len(vals) > mincnt:
  3825. lattice2[i, j] = reduce_C_function(vals)
  3826. else:
  3827. lattice2[i, j] = np.nan
  3828. accum = np.hstack((lattice1.astype(float).ravel(),
  3829. lattice2.astype(float).ravel()))
  3830. good_idxs = ~np.isnan(accum)
  3831. offsets = np.zeros((n, 2), float)
  3832. offsets[:nx1 * ny1, 0] = np.repeat(np.arange(nx1), ny1)
  3833. offsets[:nx1 * ny1, 1] = np.tile(np.arange(ny1), nx1)
  3834. offsets[nx1 * ny1:, 0] = np.repeat(np.arange(nx2) + 0.5, ny2)
  3835. offsets[nx1 * ny1:, 1] = np.tile(np.arange(ny2), nx2) + 0.5
  3836. offsets[:, 0] *= sx
  3837. offsets[:, 1] *= sy
  3838. offsets[:, 0] += xmin
  3839. offsets[:, 1] += ymin
  3840. # remove accumulation bins with no data
  3841. offsets = offsets[good_idxs, :]
  3842. accum = accum[good_idxs]
  3843. polygon = [sx, sy / 3] * np.array(
  3844. [[.5, -.5], [.5, .5], [0., 1.], [-.5, .5], [-.5, -.5], [0., -1.]])
  3845. if linewidths is None:
  3846. linewidths = [1.0]
  3847. if xscale == 'log' or yscale == 'log':
  3848. polygons = np.expand_dims(polygon, 0) + np.expand_dims(offsets, 1)
  3849. if xscale == 'log':
  3850. polygons[:, :, 0] = 10.0 ** polygons[:, :, 0]
  3851. xmin = 10.0 ** xmin
  3852. xmax = 10.0 ** xmax
  3853. self.set_xscale(xscale)
  3854. if yscale == 'log':
  3855. polygons[:, :, 1] = 10.0 ** polygons[:, :, 1]
  3856. ymin = 10.0 ** ymin
  3857. ymax = 10.0 ** ymax
  3858. self.set_yscale(yscale)
  3859. collection = mcoll.PolyCollection(
  3860. polygons,
  3861. edgecolors=edgecolors,
  3862. linewidths=linewidths,
  3863. )
  3864. else:
  3865. collection = mcoll.PolyCollection(
  3866. [polygon],
  3867. edgecolors=edgecolors,
  3868. linewidths=linewidths,
  3869. offsets=offsets,
  3870. transOffset=mtransforms.IdentityTransform(),
  3871. offset_position="data"
  3872. )
  3873. # Set normalizer if bins is 'log'
  3874. if bins == 'log':
  3875. if norm is not None:
  3876. cbook._warn_external("Only one of 'bins' and 'norm' "
  3877. "arguments can be supplied, ignoring "
  3878. "bins={}".format(bins))
  3879. else:
  3880. norm = mcolors.LogNorm()
  3881. bins = None
  3882. if isinstance(norm, mcolors.LogNorm):
  3883. if (accum == 0).any():
  3884. # make sure we have no zeros
  3885. accum += 1
  3886. # autoscale the norm with curren accum values if it hasn't
  3887. # been set
  3888. if norm is not None:
  3889. if norm.vmin is None and norm.vmax is None:
  3890. norm.autoscale(accum)
  3891. if bins is not None:
  3892. if not np.iterable(bins):
  3893. minimum, maximum = min(accum), max(accum)
  3894. bins -= 1 # one less edge than bins
  3895. bins = minimum + (maximum - minimum) * np.arange(bins) / bins
  3896. bins = np.sort(bins)
  3897. accum = bins.searchsorted(accum)
  3898. collection.set_array(accum)
  3899. collection.set_cmap(cmap)
  3900. collection.set_norm(norm)
  3901. collection.set_alpha(alpha)
  3902. collection.update(kwargs)
  3903. if vmin is not None or vmax is not None:
  3904. collection.set_clim(vmin, vmax)
  3905. else:
  3906. collection.autoscale_None()
  3907. corners = ((xmin, ymin), (xmax, ymax))
  3908. self.update_datalim(corners)
  3909. self._request_autoscale_view(tight=True)
  3910. # add the collection last
  3911. self.add_collection(collection, autolim=False)
  3912. if not marginals:
  3913. return collection
  3914. if C is None:
  3915. C = np.ones(len(x))
  3916. def coarse_bin(x, y, coarse):
  3917. ind = coarse.searchsorted(x).clip(0, len(coarse) - 1)
  3918. mus = np.zeros(len(coarse))
  3919. for i in range(len(coarse)):
  3920. yi = y[ind == i]
  3921. if len(yi) > 0:
  3922. mu = reduce_C_function(yi)
  3923. else:
  3924. mu = np.nan
  3925. mus[i] = mu
  3926. return mus
  3927. coarse = np.linspace(xmin, xmax, gridsize)
  3928. xcoarse = coarse_bin(xorig, C, coarse)
  3929. valid = ~np.isnan(xcoarse)
  3930. verts, values = [], []
  3931. for i, val in enumerate(xcoarse):
  3932. thismin = coarse[i]
  3933. if i < len(coarse) - 1:
  3934. thismax = coarse[i + 1]
  3935. else:
  3936. thismax = thismin + np.diff(coarse)[-1]
  3937. if not valid[i]:
  3938. continue
  3939. verts.append([(thismin, 0),
  3940. (thismin, 0.05),
  3941. (thismax, 0.05),
  3942. (thismax, 0)])
  3943. values.append(val)
  3944. values = np.array(values)
  3945. trans = self.get_xaxis_transform(which='grid')
  3946. hbar = mcoll.PolyCollection(verts, transform=trans, edgecolors='face')
  3947. hbar.set_array(values)
  3948. hbar.set_cmap(cmap)
  3949. hbar.set_norm(norm)
  3950. hbar.set_alpha(alpha)
  3951. hbar.update(kwargs)
  3952. self.add_collection(hbar, autolim=False)
  3953. coarse = np.linspace(ymin, ymax, gridsize)
  3954. ycoarse = coarse_bin(yorig, C, coarse)
  3955. valid = ~np.isnan(ycoarse)
  3956. verts, values = [], []
  3957. for i, val in enumerate(ycoarse):
  3958. thismin = coarse[i]
  3959. if i < len(coarse) - 1:
  3960. thismax = coarse[i + 1]
  3961. else:
  3962. thismax = thismin + np.diff(coarse)[-1]
  3963. if not valid[i]:
  3964. continue
  3965. verts.append([(0, thismin), (0.0, thismax),
  3966. (0.05, thismax), (0.05, thismin)])
  3967. values.append(val)
  3968. values = np.array(values)
  3969. trans = self.get_yaxis_transform(which='grid')
  3970. vbar = mcoll.PolyCollection(verts, transform=trans, edgecolors='face')
  3971. vbar.set_array(values)
  3972. vbar.set_cmap(cmap)
  3973. vbar.set_norm(norm)
  3974. vbar.set_alpha(alpha)
  3975. vbar.update(kwargs)
  3976. self.add_collection(vbar, autolim=False)
  3977. collection.hbar = hbar
  3978. collection.vbar = vbar
  3979. def on_changed(collection):
  3980. hbar.set_cmap(collection.get_cmap())
  3981. hbar.set_clim(collection.get_clim())
  3982. vbar.set_cmap(collection.get_cmap())
  3983. vbar.set_clim(collection.get_clim())
  3984. collection.callbacksSM.connect('changed', on_changed)
  3985. return collection
  3986. @docstring.dedent_interpd
  3987. def arrow(self, x, y, dx, dy, **kwargs):
  3988. """
  3989. Add an arrow to the axes.
  3990. This draws an arrow from ``(x, y)`` to ``(x+dx, y+dy)``.
  3991. Parameters
  3992. ----------
  3993. x, y : float
  3994. The x and y coordinates of the arrow base.
  3995. dx, dy : float
  3996. The length of the arrow along x and y direction.
  3997. Returns
  3998. -------
  3999. arrow : `.FancyArrow`
  4000. The created `.FancyArrow` object.
  4001. Other Parameters
  4002. ----------------
  4003. **kwargs
  4004. Optional kwargs (inherited from `.FancyArrow` patch) control the
  4005. arrow construction and properties:
  4006. %(FancyArrow)s
  4007. Notes
  4008. -----
  4009. The resulting arrow is affected by the axes aspect ratio and limits.
  4010. This may produce an arrow whose head is not square with its stem. To
  4011. create an arrow whose head is square with its stem,
  4012. use :meth:`annotate` for example:
  4013. >>> ax.annotate("", xy=(0.5, 0.5), xytext=(0, 0),
  4014. ... arrowprops=dict(arrowstyle="->"))
  4015. """
  4016. # Strip away units for the underlying patch since units
  4017. # do not make sense to most patch-like code
  4018. x = self.convert_xunits(x)
  4019. y = self.convert_yunits(y)
  4020. dx = self.convert_xunits(dx)
  4021. dy = self.convert_yunits(dy)
  4022. a = mpatches.FancyArrow(x, y, dx, dy, **kwargs)
  4023. self.add_artist(a)
  4024. return a
  4025. @docstring.copy(mquiver.QuiverKey.__init__)
  4026. def quiverkey(self, Q, X, Y, U, label, **kw):
  4027. qk = mquiver.QuiverKey(Q, X, Y, U, label, **kw)
  4028. self.add_artist(qk)
  4029. return qk
  4030. # Handle units for x and y, if they've been passed
  4031. def _quiver_units(self, args, kw):
  4032. if len(args) > 3:
  4033. x, y = args[0:2]
  4034. self._process_unit_info(xdata=x, ydata=y, kwargs=kw)
  4035. x = self.convert_xunits(x)
  4036. y = self.convert_yunits(y)
  4037. return (x, y) + args[2:]
  4038. return args
  4039. # args can by a combination if X, Y, U, V, C and all should be replaced
  4040. @_preprocess_data()
  4041. def quiver(self, *args, **kw):
  4042. # Make sure units are handled for x and y values
  4043. args = self._quiver_units(args, kw)
  4044. q = mquiver.Quiver(self, *args, **kw)
  4045. self.add_collection(q, autolim=True)
  4046. self._request_autoscale_view()
  4047. return q
  4048. quiver.__doc__ = mquiver.Quiver.quiver_doc
  4049. # args can be some combination of X, Y, U, V, C and all should be replaced
  4050. @_preprocess_data()
  4051. @docstring.dedent_interpd
  4052. def barbs(self, *args, **kw):
  4053. """
  4054. %(barbs_doc)s
  4055. """
  4056. # Make sure units are handled for x and y values
  4057. args = self._quiver_units(args, kw)
  4058. b = mquiver.Barbs(self, *args, **kw)
  4059. self.add_collection(b, autolim=True)
  4060. self._request_autoscale_view()
  4061. return b
  4062. # Uses a custom implementation of data-kwarg handling in
  4063. # _process_plot_var_args.
  4064. def fill(self, *args, data=None, **kwargs):
  4065. """
  4066. Plot filled polygons.
  4067. Parameters
  4068. ----------
  4069. *args : sequence of x, y, [color]
  4070. Each polygon is defined by the lists of *x* and *y* positions of
  4071. its nodes, optionally followed by a *color* specifier. See
  4072. :mod:`matplotlib.colors` for supported color specifiers. The
  4073. standard color cycle is used for polygons without a color
  4074. specifier.
  4075. You can plot multiple polygons by providing multiple *x*, *y*,
  4076. *[color]* groups.
  4077. For example, each of the following is legal::
  4078. ax.fill(x, y) # a polygon with default color
  4079. ax.fill(x, y, "b") # a blue polygon
  4080. ax.fill(x, y, x2, y2) # two polygons
  4081. ax.fill(x, y, "b", x2, y2, "r") # a blue and a red polygon
  4082. data : indexable object, optional
  4083. An object with labelled data. If given, provide the label names to
  4084. plot in *x* and *y*, e.g.::
  4085. ax.fill("time", "signal",
  4086. data={"time": [0, 1, 2], "signal": [0, 1, 0]})
  4087. Returns
  4088. -------
  4089. a list of :class:`~matplotlib.patches.Polygon`
  4090. Other Parameters
  4091. ----------------
  4092. **kwargs : :class:`~matplotlib.patches.Polygon` properties
  4093. Notes
  4094. -----
  4095. Use :meth:`fill_between` if you would like to fill the region between
  4096. two curves.
  4097. """
  4098. # For compatibility(!), get aliases from Line2D rather than Patch.
  4099. kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)
  4100. # _get_patches_for_fill returns a generator, convert it to a list.
  4101. patches = [*self._get_patches_for_fill(*args, data=data, **kwargs)]
  4102. for poly in patches:
  4103. self.add_patch(poly)
  4104. self._request_autoscale_view()
  4105. return patches
  4106. @_preprocess_data(replace_names=["x", "y1", "y2", "where"])
  4107. @docstring.dedent_interpd
  4108. def fill_between(self, x, y1, y2=0, where=None, interpolate=False,
  4109. step=None, **kwargs):
  4110. """
  4111. Fill the area between two horizontal curves.
  4112. The curves are defined by the points (*x*, *y1*) and (*x*, *y2*). This
  4113. creates one or multiple polygons describing the filled area.
  4114. You may exclude some horizontal sections from filling using *where*.
  4115. By default, the edges connect the given points directly. Use *step* if
  4116. the filling should be a step function, i.e. constant in between *x*.
  4117. Parameters
  4118. ----------
  4119. x : array (length N)
  4120. The x coordinates of the nodes defining the curves.
  4121. y1 : array (length N) or scalar
  4122. The y coordinates of the nodes defining the first curve.
  4123. y2 : array (length N) or scalar, optional, default: 0
  4124. The y coordinates of the nodes defining the second curve.
  4125. where : array of bool (length N), optional, default: None
  4126. Define *where* to exclude some horizontal regions from being
  4127. filled. The filled regions are defined by the coordinates
  4128. ``x[where]``. More precisely, fill between ``x[i]`` and ``x[i+1]``
  4129. if ``where[i] and where[i+1]``. Note that this definition implies
  4130. that an isolated *True* value between two *False* values in
  4131. *where* will not result in filling. Both sides of the *True*
  4132. position remain unfilled due to the adjacent *False* values.
  4133. interpolate : bool, optional
  4134. This option is only relevant if *where* is used and the two curves
  4135. are crossing each other.
  4136. Semantically, *where* is often used for *y1* > *y2* or similar.
  4137. By default, the nodes of the polygon defining the filled region
  4138. will only be placed at the positions in the *x* array. Such a
  4139. polygon cannot describe the above semantics close to the
  4140. intersection. The x-sections containing the intersection are
  4141. simply clipped.
  4142. Setting *interpolate* to *True* will calculate the actual
  4143. intersection point and extend the filled region up to this point.
  4144. step : {'pre', 'post', 'mid'}, optional
  4145. Define *step* if the filling should be a step function,
  4146. i.e. constant in between *x*. The value determines where the
  4147. step will occur:
  4148. - 'pre': The y value is continued constantly to the left from
  4149. every *x* position, i.e. the interval ``(x[i-1], x[i]]`` has the
  4150. value ``y[i]``.
  4151. - 'post': The y value is continued constantly to the right from
  4152. every *x* position, i.e. the interval ``[x[i], x[i+1])`` has the
  4153. value ``y[i]``.
  4154. - 'mid': Steps occur half-way between the *x* positions.
  4155. Other Parameters
  4156. ----------------
  4157. **kwargs
  4158. All other keyword arguments are passed on to `.PolyCollection`.
  4159. They control the `.Polygon` properties:
  4160. %(PolyCollection)s
  4161. Returns
  4162. -------
  4163. `.PolyCollection`
  4164. A `.PolyCollection` containing the plotted polygons.
  4165. See Also
  4166. --------
  4167. fill_betweenx : Fill between two sets of x-values.
  4168. Notes
  4169. -----
  4170. .. [notes section required to get data note injection right]
  4171. """
  4172. if not rcParams['_internal.classic_mode']:
  4173. kwargs = cbook.normalize_kwargs(kwargs, mcoll.Collection)
  4174. if not any(c in kwargs for c in ('color', 'facecolor')):
  4175. kwargs['facecolor'] = \
  4176. self._get_patches_for_fill.get_next_color()
  4177. # Handle united data, such as dates
  4178. self._process_unit_info(xdata=x, ydata=y1, kwargs=kwargs)
  4179. self._process_unit_info(ydata=y2)
  4180. # Convert the arrays so we can work with them
  4181. x = ma.masked_invalid(self.convert_xunits(x))
  4182. y1 = ma.masked_invalid(self.convert_yunits(y1))
  4183. y2 = ma.masked_invalid(self.convert_yunits(y2))
  4184. for name, array in [('x', x), ('y1', y1), ('y2', y2)]:
  4185. if array.ndim > 1:
  4186. raise ValueError('Input passed into argument "%r"' % name +
  4187. 'is not 1-dimensional.')
  4188. if where is None:
  4189. where = True
  4190. else:
  4191. where = np.asarray(where, dtype=bool)
  4192. if where.size != x.size:
  4193. cbook.warn_deprecated(
  4194. "3.2",
  4195. message="The parameter where must have the same size as x "
  4196. "in fill_between(). This will become an error in "
  4197. "future versions of Matplotlib.")
  4198. where = where & ~functools.reduce(np.logical_or,
  4199. map(np.ma.getmask, [x, y1, y2]))
  4200. x, y1, y2 = np.broadcast_arrays(np.atleast_1d(x), y1, y2)
  4201. polys = []
  4202. for ind0, ind1 in cbook.contiguous_regions(where):
  4203. xslice = x[ind0:ind1]
  4204. y1slice = y1[ind0:ind1]
  4205. y2slice = y2[ind0:ind1]
  4206. if step is not None:
  4207. step_func = cbook.STEP_LOOKUP_MAP["steps-" + step]
  4208. xslice, y1slice, y2slice = step_func(xslice, y1slice, y2slice)
  4209. if not len(xslice):
  4210. continue
  4211. N = len(xslice)
  4212. X = np.zeros((2 * N + 2, 2), float)
  4213. if interpolate:
  4214. def get_interp_point(ind):
  4215. im1 = max(ind - 1, 0)
  4216. x_values = x[im1:ind + 1]
  4217. diff_values = y1[im1:ind + 1] - y2[im1:ind + 1]
  4218. y1_values = y1[im1:ind + 1]
  4219. if len(diff_values) == 2:
  4220. if np.ma.is_masked(diff_values[1]):
  4221. return x[im1], y1[im1]
  4222. elif np.ma.is_masked(diff_values[0]):
  4223. return x[ind], y1[ind]
  4224. diff_order = diff_values.argsort()
  4225. diff_root_x = np.interp(
  4226. 0, diff_values[diff_order], x_values[diff_order])
  4227. x_order = x_values.argsort()
  4228. diff_root_y = np.interp(diff_root_x, x_values[x_order],
  4229. y1_values[x_order])
  4230. return diff_root_x, diff_root_y
  4231. start = get_interp_point(ind0)
  4232. end = get_interp_point(ind1)
  4233. else:
  4234. # the purpose of the next two lines is for when y2 is a
  4235. # scalar like 0 and we want the fill to go all the way
  4236. # down to 0 even if none of the y1 sample points do
  4237. start = xslice[0], y2slice[0]
  4238. end = xslice[-1], y2slice[-1]
  4239. X[0] = start
  4240. X[N + 1] = end
  4241. X[1:N + 1, 0] = xslice
  4242. X[1:N + 1, 1] = y1slice
  4243. X[N + 2:, 0] = xslice[::-1]
  4244. X[N + 2:, 1] = y2slice[::-1]
  4245. polys.append(X)
  4246. collection = mcoll.PolyCollection(polys, **kwargs)
  4247. # now update the datalim and autoscale
  4248. XY1 = np.array([x[where], y1[where]]).T
  4249. XY2 = np.array([x[where], y2[where]]).T
  4250. self.dataLim.update_from_data_xy(XY1, self.ignore_existing_data_limits,
  4251. updatex=True, updatey=True)
  4252. self.ignore_existing_data_limits = False
  4253. self.dataLim.update_from_data_xy(XY2, self.ignore_existing_data_limits,
  4254. updatex=False, updatey=True)
  4255. self.add_collection(collection, autolim=False)
  4256. self._request_autoscale_view()
  4257. return collection
  4258. @_preprocess_data(replace_names=["y", "x1", "x2", "where"])
  4259. @docstring.dedent_interpd
  4260. def fill_betweenx(self, y, x1, x2=0, where=None,
  4261. step=None, interpolate=False, **kwargs):
  4262. """
  4263. Fill the area between two vertical curves.
  4264. The curves are defined by the points (*x1*, *y*) and (*x2*, *y*). This
  4265. creates one or multiple polygons describing the filled area.
  4266. You may exclude some vertical sections from filling using *where*.
  4267. By default, the edges connect the given points directly. Use *step* if
  4268. the filling should be a step function, i.e. constant in between *y*.
  4269. Parameters
  4270. ----------
  4271. y : array (length N)
  4272. The y coordinates of the nodes defining the curves.
  4273. x1 : array (length N) or scalar
  4274. The x coordinates of the nodes defining the first curve.
  4275. x2 : array (length N) or scalar, optional, default: 0
  4276. The x coordinates of the nodes defining the second curve.
  4277. where : array of bool (length N), optional, default: None
  4278. Define *where* to exclude some vertical regions from being
  4279. filled. The filled regions are defined by the coordinates
  4280. ``y[where]``. More precisely, fill between ``y[i]`` and ``y[i+1]``
  4281. if ``where[i] and where[i+1]``. Note that this definition implies
  4282. that an isolated *True* value between two *False* values in
  4283. *where* will not result in filling. Both sides of the *True*
  4284. position remain unfilled due to the adjacent *False* values.
  4285. interpolate : bool, optional
  4286. This option is only relevant if *where* is used and the two curves
  4287. are crossing each other.
  4288. Semantically, *where* is often used for *x1* > *x2* or similar.
  4289. By default, the nodes of the polygon defining the filled region
  4290. will only be placed at the positions in the *y* array. Such a
  4291. polygon cannot describe the above semantics close to the
  4292. intersection. The y-sections containing the intersection are
  4293. simply clipped.
  4294. Setting *interpolate* to *True* will calculate the actual
  4295. intersection point and extend the filled region up to this point.
  4296. step : {'pre', 'post', 'mid'}, optional
  4297. Define *step* if the filling should be a step function,
  4298. i.e. constant in between *y*. The value determines where the
  4299. step will occur:
  4300. - 'pre': The y value is continued constantly to the left from
  4301. every *x* position, i.e. the interval ``(x[i-1], x[i]]`` has the
  4302. value ``y[i]``.
  4303. - 'post': The y value is continued constantly to the right from
  4304. every *x* position, i.e. the interval ``[x[i], x[i+1])`` has the
  4305. value ``y[i]``.
  4306. - 'mid': Steps occur half-way between the *x* positions.
  4307. Other Parameters
  4308. ----------------
  4309. **kwargs
  4310. All other keyword arguments are passed on to `.PolyCollection`.
  4311. They control the `.Polygon` properties:
  4312. %(PolyCollection)s
  4313. Returns
  4314. -------
  4315. `.PolyCollection`
  4316. A `.PolyCollection` containing the plotted polygons.
  4317. See Also
  4318. --------
  4319. fill_between : Fill between two sets of y-values.
  4320. Notes
  4321. -----
  4322. .. [notes section required to get data note injection right]
  4323. """
  4324. if not rcParams['_internal.classic_mode']:
  4325. kwargs = cbook.normalize_kwargs(kwargs, mcoll.Collection)
  4326. if not any(c in kwargs for c in ('color', 'facecolor')):
  4327. kwargs['facecolor'] = \
  4328. self._get_patches_for_fill.get_next_color()
  4329. # Handle united data, such as dates
  4330. self._process_unit_info(ydata=y, xdata=x1, kwargs=kwargs)
  4331. self._process_unit_info(xdata=x2)
  4332. # Convert the arrays so we can work with them
  4333. y = ma.masked_invalid(self.convert_yunits(y))
  4334. x1 = ma.masked_invalid(self.convert_xunits(x1))
  4335. x2 = ma.masked_invalid(self.convert_xunits(x2))
  4336. for name, array in [('y', y), ('x1', x1), ('x2', x2)]:
  4337. if array.ndim > 1:
  4338. raise ValueError('Input passed into argument "%r"' % name +
  4339. 'is not 1-dimensional.')
  4340. if where is None:
  4341. where = True
  4342. else:
  4343. where = np.asarray(where, dtype=bool)
  4344. if where.size != y.size:
  4345. cbook.warn_deprecated(
  4346. "3.2",
  4347. message="The parameter where must have the same size as y "
  4348. "in fill_between(). This will become an error in "
  4349. "future versions of Matplotlib.")
  4350. where = where & ~functools.reduce(np.logical_or,
  4351. map(np.ma.getmask, [y, x1, x2]))
  4352. y, x1, x2 = np.broadcast_arrays(np.atleast_1d(y), x1, x2)
  4353. polys = []
  4354. for ind0, ind1 in cbook.contiguous_regions(where):
  4355. yslice = y[ind0:ind1]
  4356. x1slice = x1[ind0:ind1]
  4357. x2slice = x2[ind0:ind1]
  4358. if step is not None:
  4359. step_func = cbook.STEP_LOOKUP_MAP["steps-" + step]
  4360. yslice, x1slice, x2slice = step_func(yslice, x1slice, x2slice)
  4361. if not len(yslice):
  4362. continue
  4363. N = len(yslice)
  4364. Y = np.zeros((2 * N + 2, 2), float)
  4365. if interpolate:
  4366. def get_interp_point(ind):
  4367. im1 = max(ind - 1, 0)
  4368. y_values = y[im1:ind + 1]
  4369. diff_values = x1[im1:ind + 1] - x2[im1:ind + 1]
  4370. x1_values = x1[im1:ind + 1]
  4371. if len(diff_values) == 2:
  4372. if np.ma.is_masked(diff_values[1]):
  4373. return x1[im1], y[im1]
  4374. elif np.ma.is_masked(diff_values[0]):
  4375. return x1[ind], y[ind]
  4376. diff_order = diff_values.argsort()
  4377. diff_root_y = np.interp(
  4378. 0, diff_values[diff_order], y_values[diff_order])
  4379. y_order = y_values.argsort()
  4380. diff_root_x = np.interp(diff_root_y, y_values[y_order],
  4381. x1_values[y_order])
  4382. return diff_root_x, diff_root_y
  4383. start = get_interp_point(ind0)
  4384. end = get_interp_point(ind1)
  4385. else:
  4386. # the purpose of the next two lines is for when x2 is a
  4387. # scalar like 0 and we want the fill to go all the way
  4388. # down to 0 even if none of the x1 sample points do
  4389. start = x2slice[0], yslice[0]
  4390. end = x2slice[-1], yslice[-1]
  4391. Y[0] = start
  4392. Y[N + 1] = end
  4393. Y[1:N + 1, 0] = x1slice
  4394. Y[1:N + 1, 1] = yslice
  4395. Y[N + 2:, 0] = x2slice[::-1]
  4396. Y[N + 2:, 1] = yslice[::-1]
  4397. polys.append(Y)
  4398. collection = mcoll.PolyCollection(polys, **kwargs)
  4399. # now update the datalim and autoscale
  4400. X1Y = np.array([x1[where], y[where]]).T
  4401. X2Y = np.array([x2[where], y[where]]).T
  4402. self.dataLim.update_from_data_xy(X1Y, self.ignore_existing_data_limits,
  4403. updatex=True, updatey=True)
  4404. self.ignore_existing_data_limits = False
  4405. self.dataLim.update_from_data_xy(X2Y, self.ignore_existing_data_limits,
  4406. updatex=True, updatey=False)
  4407. self.add_collection(collection, autolim=False)
  4408. self._request_autoscale_view()
  4409. return collection
  4410. #### plotting z(x, y): imshow, pcolor and relatives, contour
  4411. @_preprocess_data()
  4412. @cbook._delete_parameter("3.1", "shape")
  4413. @cbook._delete_parameter("3.1", "imlim")
  4414. def imshow(self, X, cmap=None, norm=None, aspect=None,
  4415. interpolation=None, alpha=None, vmin=None, vmax=None,
  4416. origin=None, extent=None, shape=None, filternorm=1,
  4417. filterrad=4.0, imlim=None, resample=None, url=None, **kwargs):
  4418. """
  4419. Display data as an image; i.e. on a 2D regular raster.
  4420. The input may either be actual RGB(A) data, or 2D scalar data, which
  4421. will be rendered as a pseudocolor image. Note: For actually displaying
  4422. a grayscale image set up the color mapping using the parameters
  4423. ``cmap='gray', vmin=0, vmax=255``.
  4424. Parameters
  4425. ----------
  4426. X : array-like or PIL image
  4427. The image data. Supported array shapes are:
  4428. - (M, N): an image with scalar data. The values are mapped to
  4429. colors using normalization and a colormap. See parameters *norm*,
  4430. *cmap*, *vmin*, *vmax*.
  4431. - (M, N, 3): an image with RGB values (0-1 float or 0-255 int).
  4432. - (M, N, 4): an image with RGBA values (0-1 float or 0-255 int),
  4433. i.e. including transparency.
  4434. The first two dimensions (M, N) define the rows and columns of
  4435. the image.
  4436. Out-of-range RGB(A) values are clipped.
  4437. cmap : str or `~matplotlib.colors.Colormap`, optional
  4438. The Colormap instance or registered colormap name used to map
  4439. scalar data to colors. This parameter is ignored for RGB(A) data.
  4440. Defaults to :rc:`image.cmap`.
  4441. norm : `~matplotlib.colors.Normalize`, optional
  4442. The `Normalize` instance used to scale scalar data to the [0, 1]
  4443. range before mapping to colors using *cmap*. By default, a linear
  4444. scaling mapping the lowest value to 0 and the highest to 1 is used.
  4445. This parameter is ignored for RGB(A) data.
  4446. aspect : {'equal', 'auto'} or float, optional
  4447. Controls the aspect ratio of the axes. The aspect is of particular
  4448. relevance for images since it may distort the image, i.e. pixel
  4449. will not be square.
  4450. This parameter is a shortcut for explicitly calling
  4451. `.Axes.set_aspect`. See there for further details.
  4452. - 'equal': Ensures an aspect ratio of 1. Pixels will be square
  4453. (unless pixel sizes are explicitly made non-square in data
  4454. coordinates using *extent*).
  4455. - 'auto': The axes is kept fixed and the aspect is adjusted so
  4456. that the data fit in the axes. In general, this will result in
  4457. non-square pixels.
  4458. If not given, use :rc:`image.aspect`.
  4459. interpolation : str, optional
  4460. The interpolation method used. If *None*, :rc:`image.interpolation`
  4461. is used.
  4462. Supported values are 'none', 'antialiased', 'nearest', 'bilinear',
  4463. 'bicubic', 'spline16', 'spline36', 'hanning', 'hamming', 'hermite',
  4464. 'kaiser', 'quadric', 'catrom', 'gaussian', 'bessel', 'mitchell',
  4465. 'sinc', 'lanczos'.
  4466. If *interpolation* is 'none', then no interpolation is performed
  4467. on the Agg, ps, pdf and svg backends. Other backends will fall back
  4468. to 'nearest'. Note that most SVG renders perform interpolation at
  4469. rendering and that the default interpolation method they implement
  4470. may differ.
  4471. If *interpolation* is the default 'antialiased', then 'nearest'
  4472. interpolation is used if the image is upsampled by more than a
  4473. factor of three (i.e. the number of display pixels is at least
  4474. three times the size of the data array). If the upsampling rate is
  4475. smaller than 3, or the image is downsampled, then 'hanning'
  4476. interpolation is used to act as an anti-aliasing filter, unless the
  4477. image happens to be upsampled by exactly a factor of two or one.
  4478. See
  4479. :doc:`/gallery/images_contours_and_fields/interpolation_methods`
  4480. for an overview of the supported interpolation methods, and
  4481. :doc:`/gallery/images_contours_and_fields/image_antialiasing` for
  4482. a discussion of image antialiasing.
  4483. Some interpolation methods require an additional radius parameter,
  4484. which can be set by *filterrad*. Additionally, the antigrain image
  4485. resize filter is controlled by the parameter *filternorm*.
  4486. alpha : scalar or array-like, optional
  4487. The alpha blending value, between 0 (transparent) and 1 (opaque).
  4488. If *alpha* is an array, the alpha blending values are applied pixel
  4489. by pixel, and *alpha* must have the same shape as *X*.
  4490. vmin, vmax : scalar, optional
  4491. When using scalar data and no explicit *norm*, *vmin* and *vmax*
  4492. define the data range that the colormap covers. By default,
  4493. the colormap covers the complete value range of the supplied
  4494. data. *vmin*, *vmax* are ignored if the *norm* parameter is used.
  4495. origin : {'upper', 'lower'}, optional
  4496. Place the [0, 0] index of the array in the upper left or lower left
  4497. corner of the axes. The convention 'upper' is typically used for
  4498. matrices and images.
  4499. If not given, :rc:`image.origin` is used, defaulting to 'upper'.
  4500. Note that the vertical axes points upward for 'lower'
  4501. but downward for 'upper'.
  4502. See the :doc:`/tutorials/intermediate/imshow_extent` tutorial for
  4503. examples and a more detailed description.
  4504. extent : scalars (left, right, bottom, top), optional
  4505. The bounding box in data coordinates that the image will fill.
  4506. The image is stretched individually along x and y to fill the box.
  4507. The default extent is determined by the following conditions.
  4508. Pixels have unit size in data coordinates. Their centers are on
  4509. integer coordinates, and their center coordinates range from 0 to
  4510. columns-1 horizontally and from 0 to rows-1 vertically.
  4511. Note that the direction of the vertical axis and thus the default
  4512. values for top and bottom depend on *origin*:
  4513. - For ``origin == 'upper'`` the default is
  4514. ``(-0.5, numcols-0.5, numrows-0.5, -0.5)``.
  4515. - For ``origin == 'lower'`` the default is
  4516. ``(-0.5, numcols-0.5, -0.5, numrows-0.5)``.
  4517. See the :doc:`/tutorials/intermediate/imshow_extent` tutorial for
  4518. examples and a more detailed description.
  4519. filternorm : bool, optional, default: True
  4520. A parameter for the antigrain image resize filter (see the
  4521. antigrain documentation). If *filternorm* is set, the filter
  4522. normalizes integer values and corrects the rounding errors. It
  4523. doesn't do anything with the source floating point values, it
  4524. corrects only integers according to the rule of 1.0 which means
  4525. that any sum of pixel weights must be equal to 1.0. So, the
  4526. filter function must produce a graph of the proper shape.
  4527. filterrad : float > 0, optional, default: 4.0
  4528. The filter radius for filters that have a radius parameter, i.e.
  4529. when interpolation is one of: 'sinc', 'lanczos' or 'blackman'.
  4530. resample : bool, optional
  4531. When *True*, use a full resampling method. When *False*, only
  4532. resample when the output image is larger than the input image.
  4533. url : str, optional
  4534. Set the url of the created `.AxesImage`. See `.Artist.set_url`.
  4535. Returns
  4536. -------
  4537. image : `~matplotlib.image.AxesImage`
  4538. Other Parameters
  4539. ----------------
  4540. **kwargs : `~matplotlib.artist.Artist` properties
  4541. These parameters are passed on to the constructor of the
  4542. `.AxesImage` artist.
  4543. See also
  4544. --------
  4545. matshow : Plot a matrix or an array as an image.
  4546. Notes
  4547. -----
  4548. Unless *extent* is used, pixel centers will be located at integer
  4549. coordinates. In other words: the origin will coincide with the center
  4550. of pixel (0, 0).
  4551. There are two common representations for RGB images with an alpha
  4552. channel:
  4553. - Straight (unassociated) alpha: R, G, and B channels represent the
  4554. color of the pixel, disregarding its opacity.
  4555. - Premultiplied (associated) alpha: R, G, and B channels represent
  4556. the color of the pixel, adjusted for its opacity by multiplication.
  4557. `~matplotlib.pyplot.imshow` expects RGB images adopting the straight
  4558. (unassociated) alpha representation.
  4559. """
  4560. if aspect is None:
  4561. aspect = rcParams['image.aspect']
  4562. self.set_aspect(aspect)
  4563. im = mimage.AxesImage(self, cmap, norm, interpolation, origin, extent,
  4564. filternorm=filternorm, filterrad=filterrad,
  4565. resample=resample, **kwargs)
  4566. im.set_data(X)
  4567. im.set_alpha(alpha)
  4568. if im.get_clip_path() is None:
  4569. # image does not already have clipping set, clip to axes patch
  4570. im.set_clip_path(self.patch)
  4571. if vmin is not None or vmax is not None:
  4572. im.set_clim(vmin, vmax)
  4573. else:
  4574. im.autoscale_None()
  4575. im.set_url(url)
  4576. # update ax.dataLim, and, if autoscaling, set viewLim
  4577. # to tightly fit the image, regardless of dataLim.
  4578. im.set_extent(im.get_extent())
  4579. self.add_image(im)
  4580. return im
  4581. @staticmethod
  4582. def _pcolorargs(funcname, *args, allmatch=False):
  4583. # If allmatch is True, then the incoming X, Y, C must have matching
  4584. # dimensions, taking into account that X and Y can be 1-D rather than
  4585. # 2-D. This perfect match is required for Gouraud shading. For flat
  4586. # shading, X and Y specify boundaries, so we need one more boundary
  4587. # than color in each direction. For convenience, and consistent with
  4588. # Matlab, we discard the last row and/or column of C if necessary to
  4589. # meet this condition. This is done if allmatch is False.
  4590. if len(args) == 1:
  4591. C = np.asanyarray(args[0])
  4592. nrows, ncols = C.shape
  4593. if allmatch:
  4594. X, Y = np.meshgrid(np.arange(ncols), np.arange(nrows))
  4595. else:
  4596. X, Y = np.meshgrid(np.arange(ncols + 1), np.arange(nrows + 1))
  4597. C = cbook.safe_masked_invalid(C)
  4598. return X, Y, C
  4599. if len(args) == 3:
  4600. # Check x and y for bad data...
  4601. C = np.asanyarray(args[2])
  4602. X, Y = [cbook.safe_masked_invalid(a) for a in args[:2]]
  4603. if funcname == 'pcolormesh':
  4604. if np.ma.is_masked(X) or np.ma.is_masked(Y):
  4605. raise ValueError(
  4606. 'x and y arguments to pcolormesh cannot have '
  4607. 'non-finite values or be of type '
  4608. 'numpy.ma.core.MaskedArray with masked values')
  4609. # safe_masked_invalid() returns an ndarray for dtypes other
  4610. # than floating point.
  4611. if isinstance(X, np.ma.core.MaskedArray):
  4612. X = X.data # strip mask as downstream doesn't like it...
  4613. if isinstance(Y, np.ma.core.MaskedArray):
  4614. Y = Y.data
  4615. nrows, ncols = C.shape
  4616. else:
  4617. raise TypeError(
  4618. 'Illegal arguments to %s; see help(%s)' % (funcname, funcname))
  4619. Nx = X.shape[-1]
  4620. Ny = Y.shape[0]
  4621. if X.ndim != 2 or X.shape[0] == 1:
  4622. x = X.reshape(1, Nx)
  4623. X = x.repeat(Ny, axis=0)
  4624. if Y.ndim != 2 or Y.shape[1] == 1:
  4625. y = Y.reshape(Ny, 1)
  4626. Y = y.repeat(Nx, axis=1)
  4627. if X.shape != Y.shape:
  4628. raise TypeError(
  4629. 'Incompatible X, Y inputs to %s; see help(%s)' % (
  4630. funcname, funcname))
  4631. if allmatch:
  4632. if (Nx, Ny) != (ncols, nrows):
  4633. raise TypeError('Dimensions of C %s are incompatible with'
  4634. ' X (%d) and/or Y (%d); see help(%s)' % (
  4635. C.shape, Nx, Ny, funcname))
  4636. else:
  4637. if not (ncols in (Nx, Nx - 1) and nrows in (Ny, Ny - 1)):
  4638. raise TypeError('Dimensions of C %s are incompatible with'
  4639. ' X (%d) and/or Y (%d); see help(%s)' % (
  4640. C.shape, Nx, Ny, funcname))
  4641. C = C[:Ny - 1, :Nx - 1]
  4642. C = cbook.safe_masked_invalid(C)
  4643. return X, Y, C
  4644. @_preprocess_data()
  4645. @docstring.dedent_interpd
  4646. def pcolor(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
  4647. vmax=None, **kwargs):
  4648. r"""
  4649. Create a pseudocolor plot with a non-regular rectangular grid.
  4650. Call signature::
  4651. pcolor([X, Y,] C, **kwargs)
  4652. *X* and *Y* can be used to specify the corners of the quadrilaterals.
  4653. .. hint::
  4654. ``pcolor()`` can be very slow for large arrays. In most
  4655. cases you should use the similar but much faster
  4656. `~.Axes.pcolormesh` instead. See there for a discussion of the
  4657. differences.
  4658. Parameters
  4659. ----------
  4660. C : array-like
  4661. A scalar 2-D array. The values will be color-mapped.
  4662. X, Y : array-like, optional
  4663. The coordinates of the quadrilateral corners. The quadrilateral
  4664. for ``C[i, j]`` has corners at::
  4665. (X[i+1, j], Y[i+1, j]) (X[i+1, j+1], Y[i+1, j+1])
  4666. +---------+
  4667. | C[i, j] |
  4668. +---------+
  4669. (X[i, j], Y[i, j]) (X[i, j+1], Y[i, j+1])
  4670. Note that the column index corresponds to the
  4671. x-coordinate, and the row index corresponds to y. For
  4672. details, see the :ref:`Notes <axes-pcolor-grid-orientation>`
  4673. section below.
  4674. The dimensions of *X* and *Y* should be one greater than those of
  4675. *C*. Alternatively, *X*, *Y* and *C* may have equal dimensions, in
  4676. which case the last row and column of *C* will be ignored.
  4677. If *X* and/or *Y* are 1-D arrays or column vectors they will be
  4678. expanded as needed into the appropriate 2-D arrays, making a
  4679. rectangular grid.
  4680. cmap : str or `~matplotlib.colors.Colormap`, optional
  4681. A Colormap instance or registered colormap name. The colormap
  4682. maps the *C* values to colors. Defaults to :rc:`image.cmap`.
  4683. norm : `~matplotlib.colors.Normalize`, optional
  4684. The Normalize instance scales the data values to the canonical
  4685. colormap range [0, 1] for mapping to colors. By default, the data
  4686. range is mapped to the colorbar range using linear scaling.
  4687. vmin, vmax : scalar, optional, default: None
  4688. The colorbar range. If *None*, suitable min/max values are
  4689. automatically chosen by the `~.Normalize` instance (defaults to
  4690. the respective min/max values of *C* in case of the default linear
  4691. scaling).
  4692. edgecolors : {'none', None, 'face', color, color sequence}, optional
  4693. The color of the edges. Defaults to 'none'. Possible values:
  4694. - 'none' or '': No edge.
  4695. - *None*: :rc:`patch.edgecolor` will be used. Note that currently
  4696. :rc:`patch.force_edgecolor` has to be True for this to work.
  4697. - 'face': Use the adjacent face color.
  4698. - A color or sequence of colors will set the edge color.
  4699. The singular form *edgecolor* works as an alias.
  4700. alpha : scalar, optional, default: None
  4701. The alpha blending value of the face color, between 0 (transparent)
  4702. and 1 (opaque). Note: The edgecolor is currently not affected by
  4703. this.
  4704. snap : bool, optional, default: False
  4705. Whether to snap the mesh to pixel boundaries.
  4706. Returns
  4707. -------
  4708. collection : `matplotlib.collections.Collection`
  4709. Other Parameters
  4710. ----------------
  4711. antialiaseds : bool, optional, default: False
  4712. The default *antialiaseds* is False if the default
  4713. *edgecolors*\ ="none" is used. This eliminates artificial lines
  4714. at patch boundaries, and works regardless of the value of alpha.
  4715. If *edgecolors* is not "none", then the default *antialiaseds*
  4716. is taken from :rc:`patch.antialiased`.
  4717. Stroking the edges may be preferred if *alpha* is 1, but will
  4718. cause artifacts otherwise.
  4719. **kwargs
  4720. Additionally, the following arguments are allowed. They are passed
  4721. along to the `~matplotlib.collections.PolyCollection` constructor:
  4722. %(PolyCollection)s
  4723. See Also
  4724. --------
  4725. pcolormesh : for an explanation of the differences between
  4726. pcolor and pcolormesh.
  4727. imshow : If *X* and *Y* are each equidistant, `~.Axes.imshow` can be a
  4728. faster alternative.
  4729. Notes
  4730. -----
  4731. **Masked arrays**
  4732. *X*, *Y* and *C* may be masked arrays. If either ``C[i, j]``, or one
  4733. of the vertices surrounding ``C[i, j]`` (*X* or *Y* at
  4734. ``[i, j], [i+1, j], [i, j+1], [i+1, j+1]``) is masked, nothing is
  4735. plotted.
  4736. .. _axes-pcolor-grid-orientation:
  4737. **Grid orientation**
  4738. The grid orientation follows the standard matrix convention: An array
  4739. *C* with shape (nrows, ncolumns) is plotted with the column number as
  4740. *X* and the row number as *Y*.
  4741. **Handling of pcolor() end-cases**
  4742. ``pcolor()`` displays all columns of *C* if *X* and *Y* are not
  4743. specified, or if *X* and *Y* have one more column than *C*.
  4744. If *X* and *Y* have the same number of columns as *C* then the last
  4745. column of *C* is dropped. Similarly for the rows.
  4746. Note: This behavior is different from MATLAB's ``pcolor()``, which
  4747. always discards the last row and column of *C*.
  4748. """
  4749. X, Y, C = self._pcolorargs('pcolor', *args, allmatch=False)
  4750. Ny, Nx = X.shape
  4751. # unit conversion allows e.g. datetime objects as axis values
  4752. self._process_unit_info(xdata=X, ydata=Y, kwargs=kwargs)
  4753. X = self.convert_xunits(X)
  4754. Y = self.convert_yunits(Y)
  4755. # convert to MA, if necessary.
  4756. C = ma.asarray(C)
  4757. X = ma.asarray(X)
  4758. Y = ma.asarray(Y)
  4759. mask = ma.getmaskarray(X) + ma.getmaskarray(Y)
  4760. xymask = (mask[0:-1, 0:-1] + mask[1:, 1:] +
  4761. mask[0:-1, 1:] + mask[1:, 0:-1])
  4762. # don't plot if C or any of the surrounding vertices are masked.
  4763. mask = ma.getmaskarray(C) + xymask
  4764. unmask = ~mask
  4765. X1 = ma.filled(X[:-1, :-1])[unmask]
  4766. Y1 = ma.filled(Y[:-1, :-1])[unmask]
  4767. X2 = ma.filled(X[1:, :-1])[unmask]
  4768. Y2 = ma.filled(Y[1:, :-1])[unmask]
  4769. X3 = ma.filled(X[1:, 1:])[unmask]
  4770. Y3 = ma.filled(Y[1:, 1:])[unmask]
  4771. X4 = ma.filled(X[:-1, 1:])[unmask]
  4772. Y4 = ma.filled(Y[:-1, 1:])[unmask]
  4773. npoly = len(X1)
  4774. xy = np.stack([X1, Y1, X2, Y2, X3, Y3, X4, Y4, X1, Y1], axis=-1)
  4775. verts = xy.reshape((npoly, 5, 2))
  4776. C = ma.filled(C[:Ny - 1, :Nx - 1])[unmask]
  4777. linewidths = (0.25,)
  4778. if 'linewidth' in kwargs:
  4779. kwargs['linewidths'] = kwargs.pop('linewidth')
  4780. kwargs.setdefault('linewidths', linewidths)
  4781. if 'edgecolor' in kwargs:
  4782. kwargs['edgecolors'] = kwargs.pop('edgecolor')
  4783. ec = kwargs.setdefault('edgecolors', 'none')
  4784. # aa setting will default via collections to patch.antialiased
  4785. # unless the boundary is not stroked, in which case the
  4786. # default will be False; with unstroked boundaries, aa
  4787. # makes artifacts that are often disturbing.
  4788. if 'antialiased' in kwargs:
  4789. kwargs['antialiaseds'] = kwargs.pop('antialiased')
  4790. if 'antialiaseds' not in kwargs and cbook._str_lower_equal(ec, "none"):
  4791. kwargs['antialiaseds'] = False
  4792. kwargs.setdefault('snap', False)
  4793. collection = mcoll.PolyCollection(verts, **kwargs)
  4794. collection.set_alpha(alpha)
  4795. collection.set_array(C)
  4796. collection.set_cmap(cmap)
  4797. collection.set_norm(norm)
  4798. collection.set_clim(vmin, vmax)
  4799. collection.autoscale_None()
  4800. self.grid(False)
  4801. x = X.compressed()
  4802. y = Y.compressed()
  4803. # Transform from native to data coordinates?
  4804. t = collection._transform
  4805. if (not isinstance(t, mtransforms.Transform) and
  4806. hasattr(t, '_as_mpl_transform')):
  4807. t = t._as_mpl_transform(self.axes)
  4808. if t and any(t.contains_branch_seperately(self.transData)):
  4809. trans_to_data = t - self.transData
  4810. pts = np.vstack([x, y]).T.astype(float)
  4811. transformed_pts = trans_to_data.transform(pts)
  4812. x = transformed_pts[..., 0]
  4813. y = transformed_pts[..., 1]
  4814. self.add_collection(collection, autolim=False)
  4815. minx = np.min(x)
  4816. maxx = np.max(x)
  4817. miny = np.min(y)
  4818. maxy = np.max(y)
  4819. collection.sticky_edges.x[:] = [minx, maxx]
  4820. collection.sticky_edges.y[:] = [miny, maxy]
  4821. corners = (minx, miny), (maxx, maxy)
  4822. self.update_datalim(corners)
  4823. self._request_autoscale_view()
  4824. return collection
  4825. @_preprocess_data()
  4826. @docstring.dedent_interpd
  4827. def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
  4828. vmax=None, shading='flat', antialiased=False, **kwargs):
  4829. """
  4830. Create a pseudocolor plot with a non-regular rectangular grid.
  4831. Call signature::
  4832. pcolor([X, Y,] C, **kwargs)
  4833. *X* and *Y* can be used to specify the corners of the quadrilaterals.
  4834. .. note::
  4835. `~Axes.pcolormesh` is similar to `~Axes.pcolor`. It's much faster
  4836. and preferred in most cases. For a detailed discussion on the
  4837. differences see :ref:`Differences between pcolor() and pcolormesh()
  4838. <differences-pcolor-pcolormesh>`.
  4839. Parameters
  4840. ----------
  4841. C : array-like
  4842. A scalar 2-D array. The values will be color-mapped.
  4843. X, Y : array-like, optional
  4844. The coordinates of the quadrilateral corners. The quadrilateral
  4845. for ``C[i, j]`` has corners at::
  4846. (X[i+1, j], Y[i+1, j]) (X[i+1, j+1], Y[i+1, j+1])
  4847. +---------+
  4848. | C[i, j] |
  4849. +---------+
  4850. (X[i, j], Y[i, j]) (X[i, j+1], Y[i, j+1])
  4851. Note that the column index corresponds to the
  4852. x-coordinate, and the row index corresponds to y. For
  4853. details, see the :ref:`Notes <axes-pcolormesh-grid-orientation>`
  4854. section below.
  4855. The dimensions of *X* and *Y* should be one greater than those of
  4856. *C*. Alternatively, *X*, *Y* and *C* may have equal dimensions, in
  4857. which case the last row and column of *C* will be ignored.
  4858. If *X* and/or *Y* are 1-D arrays or column vectors they will be
  4859. expanded as needed into the appropriate 2-D arrays, making a
  4860. rectangular grid.
  4861. cmap : str or `~matplotlib.colors.Colormap`, optional
  4862. A Colormap instance or registered colormap name. The colormap
  4863. maps the *C* values to colors. Defaults to :rc:`image.cmap`.
  4864. norm : `~matplotlib.colors.Normalize`, optional
  4865. The Normalize instance scales the data values to the canonical
  4866. colormap range [0, 1] for mapping to colors. By default, the data
  4867. range is mapped to the colorbar range using linear scaling.
  4868. vmin, vmax : scalar, optional, default: None
  4869. The colorbar range. If *None*, suitable min/max values are
  4870. automatically chosen by the `~.Normalize` instance (defaults to
  4871. the respective min/max values of *C* in case of the default linear
  4872. scaling).
  4873. edgecolors : {'none', None, 'face', color, color sequence}, optional
  4874. The color of the edges. Defaults to 'none'. Possible values:
  4875. - 'none' or '': No edge.
  4876. - *None*: :rc:`patch.edgecolor` will be used. Note that currently
  4877. :rc:`patch.force_edgecolor` has to be True for this to work.
  4878. - 'face': Use the adjacent face color.
  4879. - A color or sequence of colors will set the edge color.
  4880. The singular form *edgecolor* works as an alias.
  4881. alpha : scalar, optional, default: None
  4882. The alpha blending value, between 0 (transparent) and 1 (opaque).
  4883. shading : {'flat', 'gouraud'}, optional
  4884. The fill style, Possible values:
  4885. - 'flat': A solid color is used for each quad. The color of the
  4886. quad (i, j), (i+1, j), (i, j+1), (i+1, j+1) is given by
  4887. ``C[i, j]``.
  4888. - 'gouraud': Each quad will be Gouraud shaded: The color of the
  4889. corners (i', j') are given by ``C[i',j']``. The color values of
  4890. the area in between is interpolated from the corner values.
  4891. When Gouraud shading is used, *edgecolors* is ignored.
  4892. snap : bool, optional, default: False
  4893. Whether to snap the mesh to pixel boundaries.
  4894. Returns
  4895. -------
  4896. mesh : `matplotlib.collections.QuadMesh`
  4897. Other Parameters
  4898. ----------------
  4899. **kwargs
  4900. Additionally, the following arguments are allowed. They are passed
  4901. along to the `~matplotlib.collections.QuadMesh` constructor:
  4902. %(QuadMesh)s
  4903. See Also
  4904. --------
  4905. pcolor : An alternative implementation with slightly different
  4906. features. For a detailed discussion on the differences see
  4907. :ref:`Differences between pcolor() and pcolormesh()
  4908. <differences-pcolor-pcolormesh>`.
  4909. imshow : If *X* and *Y* are each equidistant, `~.Axes.imshow` can be a
  4910. faster alternative.
  4911. Notes
  4912. -----
  4913. **Masked arrays**
  4914. *C* may be a masked array. If ``C[i, j]`` is masked, the corresponding
  4915. quadrilateral will be transparent. Masking of *X* and *Y* is not
  4916. supported. Use `~.Axes.pcolor` if you need this functionality.
  4917. .. _axes-pcolormesh-grid-orientation:
  4918. **Grid orientation**
  4919. The grid orientation follows the standard matrix convention: An array
  4920. *C* with shape (nrows, ncolumns) is plotted with the column number as
  4921. *X* and the row number as *Y*.
  4922. .. _differences-pcolor-pcolormesh:
  4923. **Differences between pcolor() and pcolormesh()**
  4924. Both methods are used to create a pseudocolor plot of a 2-D array
  4925. using quadrilaterals.
  4926. The main difference lies in the created object and internal data
  4927. handling:
  4928. While `~.Axes.pcolor` returns a `.PolyCollection`, `~.Axes.pcolormesh`
  4929. returns a `.QuadMesh`. The latter is more specialized for the given
  4930. purpose and thus is faster. It should almost always be preferred.
  4931. There is also a slight difference in the handling of masked arrays.
  4932. Both `~.Axes.pcolor` and `~.Axes.pcolormesh` support masked arrays
  4933. for *C*. However, only `~.Axes.pcolor` supports masked arrays for *X*
  4934. and *Y*. The reason lies in the internal handling of the masked values.
  4935. `~.Axes.pcolor` leaves out the respective polygons from the
  4936. PolyCollection. `~.Axes.pcolormesh` sets the facecolor of the masked
  4937. elements to transparent. You can see the difference when using
  4938. edgecolors. While all edges are drawn irrespective of masking in a
  4939. QuadMesh, the edge between two adjacent masked quadrilaterals in
  4940. `~.Axes.pcolor` is not drawn as the corresponding polygons do not
  4941. exist in the PolyCollection.
  4942. Another difference is the support of Gouraud shading in
  4943. `~.Axes.pcolormesh`, which is not available with `~.Axes.pcolor`.
  4944. """
  4945. shading = shading.lower()
  4946. kwargs.setdefault('edgecolors', 'None')
  4947. allmatch = (shading == 'gouraud')
  4948. X, Y, C = self._pcolorargs('pcolormesh', *args, allmatch=allmatch)
  4949. Ny, Nx = X.shape
  4950. X = X.ravel()
  4951. Y = Y.ravel()
  4952. # unit conversion allows e.g. datetime objects as axis values
  4953. self._process_unit_info(xdata=X, ydata=Y, kwargs=kwargs)
  4954. X = self.convert_xunits(X)
  4955. Y = self.convert_yunits(Y)
  4956. # convert to one dimensional arrays
  4957. C = C.ravel()
  4958. coords = np.column_stack((X, Y)).astype(float, copy=False)
  4959. collection = mcoll.QuadMesh(Nx - 1, Ny - 1, coords,
  4960. antialiased=antialiased, shading=shading,
  4961. **kwargs)
  4962. collection.set_alpha(alpha)
  4963. collection.set_array(C)
  4964. collection.set_cmap(cmap)
  4965. collection.set_norm(norm)
  4966. collection.set_clim(vmin, vmax)
  4967. collection.autoscale_None()
  4968. self.grid(False)
  4969. # Transform from native to data coordinates?
  4970. t = collection._transform
  4971. if (not isinstance(t, mtransforms.Transform) and
  4972. hasattr(t, '_as_mpl_transform')):
  4973. t = t._as_mpl_transform(self.axes)
  4974. if t and any(t.contains_branch_seperately(self.transData)):
  4975. trans_to_data = t - self.transData
  4976. coords = trans_to_data.transform(coords)
  4977. self.add_collection(collection, autolim=False)
  4978. minx, miny = np.min(coords, axis=0)
  4979. maxx, maxy = np.max(coords, axis=0)
  4980. collection.sticky_edges.x[:] = [minx, maxx]
  4981. collection.sticky_edges.y[:] = [miny, maxy]
  4982. corners = (minx, miny), (maxx, maxy)
  4983. self.update_datalim(corners)
  4984. self._request_autoscale_view()
  4985. return collection
  4986. @_preprocess_data()
  4987. @docstring.dedent_interpd
  4988. def pcolorfast(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
  4989. vmax=None, **kwargs):
  4990. """
  4991. Create a pseudocolor plot with a non-regular rectangular grid.
  4992. Call signature::
  4993. ax.pcolorfast([X, Y], C, /, **kwargs)
  4994. This method is similar to ~.Axes.pcolor` and `~.Axes.pcolormesh`.
  4995. It's designed to provide the fastest pcolor-type plotting with the
  4996. Agg backend. To achieve this, it uses different algorithms internally
  4997. depending on the complexity of the input grid (regular rectangular,
  4998. non-regular rectangular or arbitrary quadrilateral).
  4999. .. warning::
  5000. This method is experimental. Compared to `~.Axes.pcolor` or
  5001. `~.Axes.pcolormesh` it has some limitations:
  5002. - It supports only flat shading (no outlines)
  5003. - It lacks support for log scaling of the axes.
  5004. - It does not have a have a pyplot wrapper.
  5005. Parameters
  5006. ----------
  5007. C : array-like(M, N)
  5008. The image data. Supported array shapes are:
  5009. - (M, N): an image with scalar data. The data is visualized
  5010. using a colormap.
  5011. - (M, N, 3): an image with RGB values (0-1 float or 0-255 int).
  5012. - (M, N, 4): an image with RGBA values (0-1 float or 0-255 int),
  5013. i.e. including transparency.
  5014. The first two dimensions (M, N) define the rows and columns of
  5015. the image.
  5016. This parameter can only be passed positionally.
  5017. X, Y : tuple or array-like, default: ``(0, N)``, ``(0, M)``
  5018. *X* and *Y* are used to specify the coordinates of the
  5019. quadrilaterals. There are different ways to do this:
  5020. - Use tuples ``X=(xmin, xmax)`` and ``Y=(ymin, ymax)`` to define
  5021. a *uniform rectangular grid*.
  5022. The tuples define the outer edges of the grid. All individual
  5023. quadrilaterals will be of the same size. This is the fastest
  5024. version.
  5025. - Use 1D arrays *X*, *Y* to specify a *non-uniform rectangular
  5026. grid*.
  5027. In this case *X* and *Y* have to be monotonic 1D arrays of length
  5028. *N+1* and *M+1*, specifying the x and y boundaries of the cells.
  5029. The speed is intermediate. Note: The grid is checked, and if
  5030. found to be uniform the fast version is used.
  5031. - Use 2D arrays *X*, *Y* if you need an *arbitrary quadrilateral
  5032. grid* (i.e. if the quadrilaterals are not rectangular).
  5033. In this case *X* and *Y* are 2D arrays with shape (M + 1, N + 1),
  5034. specifying the x and y coordinates of the corners of the colored
  5035. quadrilaterals.
  5036. This is the most general, but the slowest to render. It may
  5037. produce faster and more compact output using ps, pdf, and
  5038. svg backends, however.
  5039. These arguments can only be passed positionally.
  5040. cmap : str or `~matplotlib.colors.Colormap`, optional
  5041. A Colormap instance or registered colormap name. The colormap
  5042. maps the *C* values to colors. Defaults to :rc:`image.cmap`.
  5043. norm : `~matplotlib.colors.Normalize`, optional
  5044. The Normalize instance scales the data values to the canonical
  5045. colormap range [0, 1] for mapping to colors. By default, the data
  5046. range is mapped to the colorbar range using linear scaling.
  5047. vmin, vmax : scalar, optional, default: None
  5048. The colorbar range. If *None*, suitable min/max values are
  5049. automatically chosen by the `~.Normalize` instance (defaults to
  5050. the respective min/max values of *C* in case of the default linear
  5051. scaling).
  5052. alpha : scalar, optional, default: None
  5053. The alpha blending value, between 0 (transparent) and 1 (opaque).
  5054. snap : bool, optional, default: False
  5055. Whether to snap the mesh to pixel boundaries.
  5056. Returns
  5057. -------
  5058. image : `.AxesImage` or `.PcolorImage` or `.QuadMesh`
  5059. The return type depends on the type of grid:
  5060. - `.AxesImage` for a regular rectangular grid.
  5061. - `.PcolorImage` for a non-regular rectangular grid.
  5062. - `.QuadMesh` for a non-rectangular grid.
  5063. Notes
  5064. -----
  5065. .. [notes section required to get data note injection right]
  5066. """
  5067. C = args[-1]
  5068. nr, nc = np.shape(C)[:2]
  5069. if len(args) == 1:
  5070. style = "image"
  5071. x = [0, nc]
  5072. y = [0, nr]
  5073. elif len(args) == 3:
  5074. x, y = args[:2]
  5075. x = np.asarray(x)
  5076. y = np.asarray(y)
  5077. if x.ndim == 1 and y.ndim == 1:
  5078. if x.size == 2 and y.size == 2:
  5079. style = "image"
  5080. else:
  5081. dx = np.diff(x)
  5082. dy = np.diff(y)
  5083. if (np.ptp(dx) < 0.01 * np.abs(dx.mean()) and
  5084. np.ptp(dy) < 0.01 * np.abs(dy.mean())):
  5085. style = "image"
  5086. else:
  5087. style = "pcolorimage"
  5088. elif x.ndim == 2 and y.ndim == 2:
  5089. style = "quadmesh"
  5090. else:
  5091. raise TypeError("arguments do not match valid signatures")
  5092. else:
  5093. raise TypeError("need 1 argument or 3 arguments")
  5094. if style == "quadmesh":
  5095. # data point in each cell is value at lower left corner
  5096. coords = np.stack([x, y], axis=-1)
  5097. if np.ndim(C) == 2:
  5098. qm_kwargs = {"array": np.ma.ravel(C)}
  5099. elif np.ndim(C) == 3:
  5100. qm_kwargs = {"color": np.ma.reshape(C, (-1, C.shape[-1]))}
  5101. else:
  5102. raise ValueError("C must be 2D or 3D")
  5103. collection = mcoll.QuadMesh(
  5104. nc, nr, coords, **qm_kwargs,
  5105. alpha=alpha, cmap=cmap, norm=norm,
  5106. antialiased=False, edgecolors="none")
  5107. self.add_collection(collection, autolim=False)
  5108. xl, xr, yb, yt = x.min(), x.max(), y.min(), y.max()
  5109. ret = collection
  5110. else: # It's one of the two image styles.
  5111. extent = xl, xr, yb, yt = x[0], x[-1], y[0], y[-1]
  5112. if style == "image":
  5113. im = mimage.AxesImage(
  5114. self, cmap, norm,
  5115. data=C, alpha=alpha, extent=extent,
  5116. interpolation='nearest', origin='lower',
  5117. **kwargs)
  5118. elif style == "pcolorimage":
  5119. im = mimage.PcolorImage(
  5120. self, x, y, C,
  5121. cmap=cmap, norm=norm, alpha=alpha, extent=extent,
  5122. **kwargs)
  5123. self.add_image(im)
  5124. ret = im
  5125. if vmin is not None or vmax is not None:
  5126. ret.set_clim(vmin, vmax)
  5127. elif np.ndim(C) == 2: # C.ndim == 3 is RGB(A) so doesn't need scaling.
  5128. ret.autoscale_None()
  5129. if ret.get_clip_path() is None:
  5130. # image does not already have clipping set, clip to axes patch
  5131. ret.set_clip_path(self.patch)
  5132. ret.sticky_edges.x[:] = [xl, xr]
  5133. ret.sticky_edges.y[:] = [yb, yt]
  5134. self.update_datalim(np.array([[xl, yb], [xr, yt]]))
  5135. self._request_autoscale_view(tight=True)
  5136. return ret
  5137. @_preprocess_data()
  5138. def contour(self, *args, **kwargs):
  5139. kwargs['filled'] = False
  5140. contours = mcontour.QuadContourSet(self, *args, **kwargs)
  5141. self._request_autoscale_view()
  5142. return contours
  5143. contour.__doc__ = mcontour.QuadContourSet._contour_doc
  5144. @_preprocess_data()
  5145. def contourf(self, *args, **kwargs):
  5146. kwargs['filled'] = True
  5147. contours = mcontour.QuadContourSet(self, *args, **kwargs)
  5148. self._request_autoscale_view()
  5149. return contours
  5150. contourf.__doc__ = mcontour.QuadContourSet._contour_doc
  5151. def clabel(self, CS, *args, **kwargs):
  5152. return CS.clabel(*args, **kwargs)
  5153. clabel.__doc__ = mcontour.ContourSet.clabel.__doc__
  5154. #### Data analysis
  5155. @_preprocess_data(replace_names=["x", 'weights'], label_namer="x")
  5156. def hist(self, x, bins=None, range=None, density=False, weights=None,
  5157. cumulative=False, bottom=None, histtype='bar', align='mid',
  5158. orientation='vertical', rwidth=None, log=False,
  5159. color=None, label=None, stacked=False, **kwargs):
  5160. """
  5161. Plot a histogram.
  5162. Compute and draw the histogram of *x*. The return value is a tuple
  5163. (*n*, *bins*, *patches*) or ([*n0*, *n1*, ...], *bins*, [*patches0*,
  5164. *patches1*,...]) if the input contains multiple data. See the
  5165. documentation of the *weights* parameter to draw a histogram of
  5166. already-binned data.
  5167. Multiple data can be provided via *x* as a list of datasets
  5168. of potentially different length ([*x0*, *x1*, ...]), or as
  5169. a 2-D ndarray in which each column is a dataset. Note that
  5170. the ndarray form is transposed relative to the list form.
  5171. Masked arrays are not supported.
  5172. The *bins*, *range*, *weights*, and *density* parameters behave as in
  5173. `numpy.histogram`.
  5174. Parameters
  5175. ----------
  5176. x : (n,) array or sequence of (n,) arrays
  5177. Input values, this takes either a single array or a sequence of
  5178. arrays which are not required to be of the same length.
  5179. bins : int or sequence or str, optional
  5180. If *bins* is an integer, it defines the number of equal-width bins
  5181. in the range.
  5182. If *bins* is a sequence, it defines the bin edges, including the
  5183. left edge of the first bin and the right edge of the last bin;
  5184. in this case, bins may be unequally spaced. All but the last
  5185. (righthand-most) bin is half-open. In other words, if *bins* is::
  5186. [1, 2, 3, 4]
  5187. then the first bin is ``[1, 2)`` (including 1, but excluding 2) and
  5188. the second ``[2, 3)``. The last bin, however, is ``[3, 4]``, which
  5189. *includes* 4.
  5190. If *bins* is a string, it is one of the binning strategies
  5191. supported by `numpy.histogram_bin_edges`: 'auto', 'fd', 'doane',
  5192. 'scott', 'stone', 'rice', 'sturges', or 'sqrt'.
  5193. The default is :rc:`hist.bins`.
  5194. range : tuple or None, optional
  5195. The lower and upper range of the bins. Lower and upper outliers
  5196. are ignored. If not provided, *range* is ``(x.min(), x.max())``.
  5197. Range has no effect if *bins* is a sequence.
  5198. If *bins* is a sequence or *range* is specified, autoscaling
  5199. is based on the specified bin range instead of the
  5200. range of x.
  5201. Default is ``None``
  5202. density : bool, optional
  5203. If ``True``, the first element of the return tuple will
  5204. be the counts normalized to form a probability density, i.e.,
  5205. the area (or integral) under the histogram will sum to 1.
  5206. This is achieved by dividing the count by the number of
  5207. observations times the bin width and not dividing by the total
  5208. number of observations. If *stacked* is also ``True``, the sum of
  5209. the histograms is normalized to 1.
  5210. Default is ``False``.
  5211. weights : (n, ) array-like or None, optional
  5212. An array of weights, of the same shape as *x*. Each value in *x*
  5213. only contributes its associated weight towards the bin count
  5214. (instead of 1). If *normed* or *density* is ``True``,
  5215. the weights are normalized, so that the integral of the density
  5216. over the range remains 1.
  5217. Default is ``None``.
  5218. This parameter can be used to draw a histogram of data that has
  5219. already been binned, e.g. using `np.histogram` (by treating each
  5220. bin as a single point with a weight equal to its count) ::
  5221. counts, bins = np.histogram(data)
  5222. plt.hist(bins[:-1], bins, weights=counts)
  5223. (or you may alternatively use `~.bar()`).
  5224. cumulative : bool or -1, optional
  5225. If ``True``, then a histogram is computed where each bin gives the
  5226. counts in that bin plus all bins for smaller values. The last bin
  5227. gives the total number of datapoints.
  5228. If *density* is also ``True`` then the histogram is normalized such
  5229. that the last bin equals 1.
  5230. If *cumulative* is a number less than 0 (e.g., -1), the direction
  5231. of accumulation is reversed. In this case, if *density* is also
  5232. ``True``, then the histogram is normalized such that the first bin
  5233. equals 1.
  5234. bottom : array-like, scalar, or None, default: None
  5235. Location of the bottom of each bin, ie. bins are drawn from
  5236. ``bottom`` to ``bottom + hist(x, bins)`` If a scalar, the bottom
  5237. of each bin is shifted by the same amount. If an array, each bin
  5238. is shifted independently and the length of bottom must match the
  5239. number of bins. If None, defaults to 0.
  5240. histtype : {'bar', 'barstacked', 'step', 'stepfilled'}, optional
  5241. The type of histogram to draw.
  5242. - 'bar' is a traditional bar-type histogram. If multiple data
  5243. are given the bars are arranged side by side.
  5244. - 'barstacked' is a bar-type histogram where multiple
  5245. data are stacked on top of each other.
  5246. - 'step' generates a lineplot that is by default unfilled.
  5247. - 'stepfilled' generates a lineplot that is by default filled.
  5248. Default is 'bar'
  5249. align : {'left', 'mid', 'right'}, optional
  5250. Controls how the histogram is plotted.
  5251. - 'left': bars are centered on the left bin edges.
  5252. - 'mid': bars are centered between the bin edges.
  5253. - 'right': bars are centered on the right bin edges.
  5254. Default is 'mid'
  5255. orientation : {'horizontal', 'vertical'}, optional
  5256. If 'horizontal', `~matplotlib.pyplot.barh` will be used for
  5257. bar-type histograms and the *bottom* kwarg will be the left edges.
  5258. rwidth : scalar or None, optional
  5259. The relative width of the bars as a fraction of the bin width. If
  5260. ``None``, automatically compute the width.
  5261. Ignored if *histtype* is 'step' or 'stepfilled'.
  5262. Default is ``None``
  5263. log : bool, optional
  5264. If ``True``, the histogram axis will be set to a log scale. If
  5265. *log* is ``True`` and *x* is a 1D array, empty bins will be
  5266. filtered out and only the non-empty ``(n, bins, patches)``
  5267. will be returned.
  5268. Default is ``False``
  5269. color : color or array-like of colors or None, optional
  5270. Color or sequence of colors, one per dataset. Default (``None``)
  5271. uses the standard line color sequence.
  5272. Default is ``None``
  5273. label : str or None, optional
  5274. String, or sequence of strings to match multiple datasets. Bar
  5275. charts yield multiple patches per dataset, but only the first gets
  5276. the label, so that the legend command will work as expected.
  5277. default is ``None``
  5278. stacked : bool, optional
  5279. If ``True``, multiple data are stacked on top of each other If
  5280. ``False`` multiple data are arranged side by side if histtype is
  5281. 'bar' or on top of each other if histtype is 'step'
  5282. Default is ``False``
  5283. Returns
  5284. -------
  5285. n : array or list of arrays
  5286. The values of the histogram bins. See *density* and *weights* for a
  5287. description of the possible semantics. If input *x* is an array,
  5288. then this is an array of length *nbins*. If input is a sequence of
  5289. arrays ``[data1, data2, ...]``, then this is a list of arrays with
  5290. the values of the histograms for each of the arrays in the same
  5291. order. The dtype of the array *n* (or of its element arrays) will
  5292. always be float even if no weighting or normalization is used.
  5293. bins : array
  5294. The edges of the bins. Length nbins + 1 (nbins left edges and right
  5295. edge of last bin). Always a single array even when multiple data
  5296. sets are passed in.
  5297. patches : list or list of lists
  5298. Silent list of individual patches used to create the histogram
  5299. or list of such list if multiple input datasets.
  5300. Other Parameters
  5301. ----------------
  5302. **kwargs : `~matplotlib.patches.Patch` properties
  5303. See also
  5304. --------
  5305. hist2d : 2D histograms
  5306. """
  5307. # Avoid shadowing the builtin.
  5308. bin_range = range
  5309. from builtins import range
  5310. if np.isscalar(x):
  5311. x = [x]
  5312. if bins is None:
  5313. bins = rcParams['hist.bins']
  5314. # Validate string inputs here to avoid cluttering subsequent code.
  5315. cbook._check_in_list(['bar', 'barstacked', 'step', 'stepfilled'],
  5316. histtype=histtype)
  5317. cbook._check_in_list(['left', 'mid', 'right'], align=align)
  5318. cbook._check_in_list(['horizontal', 'vertical'],
  5319. orientation=orientation)
  5320. if histtype == 'barstacked' and not stacked:
  5321. stacked = True
  5322. # basic input validation
  5323. input_empty = np.size(x) == 0
  5324. # Massage 'x' for processing.
  5325. x = cbook._reshape_2D(x, 'x')
  5326. nx = len(x) # number of datasets
  5327. # Process unit information
  5328. # Unit conversion is done individually on each dataset
  5329. self._process_unit_info(xdata=x[0], kwargs=kwargs)
  5330. x = [self.convert_xunits(xi) for xi in x]
  5331. if bin_range is not None:
  5332. bin_range = self.convert_xunits(bin_range)
  5333. if not cbook.is_scalar_or_string(bins):
  5334. bins = self.convert_xunits(bins)
  5335. # We need to do to 'weights' what was done to 'x'
  5336. if weights is not None:
  5337. w = cbook._reshape_2D(weights, 'weights')
  5338. else:
  5339. w = [None] * nx
  5340. if len(w) != nx:
  5341. raise ValueError('weights should have the same shape as x')
  5342. for xi, wi in zip(x, w):
  5343. if wi is not None and len(wi) != len(xi):
  5344. raise ValueError(
  5345. 'weights should have the same shape as x')
  5346. if color is None:
  5347. color = [self._get_lines.get_next_color() for i in range(nx)]
  5348. else:
  5349. color = mcolors.to_rgba_array(color)
  5350. if len(color) != nx:
  5351. error_message = (
  5352. "color kwarg must have one color per data set. %d data "
  5353. "sets and %d colors were provided" % (nx, len(color)))
  5354. raise ValueError(error_message)
  5355. hist_kwargs = dict()
  5356. # if the bin_range is not given, compute without nan numpy
  5357. # does not do this for us when guessing the range (but will
  5358. # happily ignore nans when computing the histogram).
  5359. if bin_range is None:
  5360. xmin = np.inf
  5361. xmax = -np.inf
  5362. for xi in x:
  5363. if len(xi):
  5364. # python's min/max ignore nan,
  5365. # np.minnan returns nan for all nan input
  5366. xmin = min(xmin, np.nanmin(xi))
  5367. xmax = max(xmax, np.nanmax(xi))
  5368. # make sure we have seen at least one non-nan and finite
  5369. # value before we reset the bin range
  5370. if not np.isnan([xmin, xmax]).any() and not (xmin > xmax):
  5371. bin_range = (xmin, xmax)
  5372. # If bins are not specified either explicitly or via range,
  5373. # we need to figure out the range required for all datasets,
  5374. # and supply that to np.histogram.
  5375. if not input_empty and len(x) > 1:
  5376. if weights is not None:
  5377. _w = np.concatenate(w)
  5378. else:
  5379. _w = None
  5380. bins = _histogram_bin_edges(np.concatenate(x), bins, bin_range, _w)
  5381. else:
  5382. hist_kwargs['range'] = bin_range
  5383. density = bool(density)
  5384. if density and not stacked:
  5385. hist_kwargs['density'] = density
  5386. # List to store all the top coordinates of the histograms
  5387. tops = [] # Will have shape (n_datasets, n_bins).
  5388. # Loop through datasets
  5389. for i in range(nx):
  5390. # this will automatically overwrite bins,
  5391. # so that each histogram uses the same bins
  5392. m, bins = np.histogram(x[i], bins, weights=w[i], **hist_kwargs)
  5393. tops.append(m)
  5394. tops = np.array(tops, float) # causes problems later if it's an int
  5395. if stacked:
  5396. tops = tops.cumsum(axis=0)
  5397. # If a stacked density plot, normalize so the area of all the
  5398. # stacked histograms together is 1
  5399. if density:
  5400. tops = (tops / np.diff(bins)) / tops[-1].sum()
  5401. if cumulative:
  5402. slc = slice(None)
  5403. if isinstance(cumulative, Number) and cumulative < 0:
  5404. slc = slice(None, None, -1)
  5405. if density:
  5406. tops = (tops * np.diff(bins))[:, slc].cumsum(axis=1)[:, slc]
  5407. else:
  5408. tops = tops[:, slc].cumsum(axis=1)[:, slc]
  5409. patches = []
  5410. # Save autoscale state for later restoration; turn autoscaling
  5411. # off so we can do it all a single time at the end, instead
  5412. # of having it done by bar or fill and then having to be redone.
  5413. _saved_autoscalex = self.get_autoscalex_on()
  5414. _saved_autoscaley = self.get_autoscaley_on()
  5415. self.set_autoscalex_on(False)
  5416. self.set_autoscaley_on(False)
  5417. if histtype.startswith('bar'):
  5418. totwidth = np.diff(bins)
  5419. if rwidth is not None:
  5420. dr = np.clip(rwidth, 0, 1)
  5421. elif (len(tops) > 1 and
  5422. ((not stacked) or rcParams['_internal.classic_mode'])):
  5423. dr = 0.8
  5424. else:
  5425. dr = 1.0
  5426. if histtype == 'bar' and not stacked:
  5427. width = dr * totwidth / nx
  5428. dw = width
  5429. boffset = -0.5 * dr * totwidth * (1 - 1 / nx)
  5430. elif histtype == 'barstacked' or stacked:
  5431. width = dr * totwidth
  5432. boffset, dw = 0.0, 0.0
  5433. if align == 'mid':
  5434. boffset += 0.5 * totwidth
  5435. elif align == 'right':
  5436. boffset += totwidth
  5437. if orientation == 'horizontal':
  5438. _barfunc = self.barh
  5439. bottom_kwarg = 'left'
  5440. else: # orientation == 'vertical'
  5441. _barfunc = self.bar
  5442. bottom_kwarg = 'bottom'
  5443. for m, c in zip(tops, color):
  5444. if bottom is None:
  5445. bottom = np.zeros(len(m))
  5446. if stacked:
  5447. height = m - bottom
  5448. else:
  5449. height = m
  5450. patch = _barfunc(bins[:-1]+boffset, height, width,
  5451. align='center', log=log,
  5452. color=c, **{bottom_kwarg: bottom})
  5453. patches.append(patch)
  5454. if stacked:
  5455. bottom[:] = m
  5456. boffset += dw
  5457. elif histtype.startswith('step'):
  5458. # these define the perimeter of the polygon
  5459. x = np.zeros(4 * len(bins) - 3)
  5460. y = np.zeros(4 * len(bins) - 3)
  5461. x[0:2*len(bins)-1:2], x[1:2*len(bins)-1:2] = bins, bins[:-1]
  5462. x[2*len(bins)-1:] = x[1:2*len(bins)-1][::-1]
  5463. if bottom is None:
  5464. bottom = np.zeros(len(bins) - 1)
  5465. y[1:2*len(bins)-1:2], y[2:2*len(bins):2] = bottom, bottom
  5466. y[2*len(bins)-1:] = y[1:2*len(bins)-1][::-1]
  5467. if log:
  5468. if orientation == 'horizontal':
  5469. self.set_xscale('log', nonposx='clip')
  5470. else: # orientation == 'vertical'
  5471. self.set_yscale('log', nonposy='clip')
  5472. if align == 'left':
  5473. x -= 0.5*(bins[1]-bins[0])
  5474. elif align == 'right':
  5475. x += 0.5*(bins[1]-bins[0])
  5476. # If fill kwarg is set, it will be passed to the patch collection,
  5477. # overriding this
  5478. fill = (histtype == 'stepfilled')
  5479. xvals, yvals = [], []
  5480. for m in tops:
  5481. if stacked:
  5482. # starting point for drawing polygon
  5483. y[0] = y[1]
  5484. # top of the previous polygon becomes the bottom
  5485. y[2*len(bins)-1:] = y[1:2*len(bins)-1][::-1]
  5486. # set the top of this polygon
  5487. y[1:2*len(bins)-1:2], y[2:2*len(bins):2] = (m + bottom,
  5488. m + bottom)
  5489. if orientation == 'horizontal':
  5490. xvals.append(y.copy())
  5491. yvals.append(x.copy())
  5492. else:
  5493. xvals.append(x.copy())
  5494. yvals.append(y.copy())
  5495. # stepfill is closed, step is not
  5496. split = -1 if fill else 2 * len(bins)
  5497. # add patches in reverse order so that when stacking,
  5498. # items lower in the stack are plotted on top of
  5499. # items higher in the stack
  5500. for x, y, c in reversed(list(zip(xvals, yvals, color))):
  5501. patches.append(self.fill(
  5502. x[:split], y[:split],
  5503. closed=True if fill else None,
  5504. facecolor=c,
  5505. edgecolor=None if fill else c,
  5506. fill=fill if fill else None))
  5507. for patch_list in patches:
  5508. for patch in patch_list:
  5509. if orientation == 'vertical':
  5510. patch.sticky_edges.y.append(0)
  5511. elif orientation == 'horizontal':
  5512. patch.sticky_edges.x.append(0)
  5513. # we return patches, so put it back in the expected order
  5514. patches.reverse()
  5515. self.set_autoscalex_on(_saved_autoscalex)
  5516. self.set_autoscaley_on(_saved_autoscaley)
  5517. self._request_autoscale_view()
  5518. if label is None:
  5519. labels = [None]
  5520. elif isinstance(label, str):
  5521. labels = [label]
  5522. elif not np.iterable(label):
  5523. labels = [str(label)]
  5524. else:
  5525. labels = [str(lab) for lab in label]
  5526. for patch, lbl in itertools.zip_longest(patches, labels):
  5527. if patch:
  5528. p = patch[0]
  5529. p.update(kwargs)
  5530. if lbl is not None:
  5531. p.set_label(lbl)
  5532. for p in patch[1:]:
  5533. p.update(kwargs)
  5534. p.set_label('_nolegend_')
  5535. if nx == 1:
  5536. return tops[0], bins, cbook.silent_list('Patch', patches[0])
  5537. else:
  5538. return tops, bins, cbook.silent_list('Lists of Patches', patches)
  5539. @_preprocess_data(replace_names=["x", "y", "weights"])
  5540. @cbook._rename_parameter("3.1", "normed", "density")
  5541. def hist2d(self, x, y, bins=10, range=None, density=False, weights=None,
  5542. cmin=None, cmax=None, **kwargs):
  5543. """
  5544. Make a 2D histogram plot.
  5545. Parameters
  5546. ----------
  5547. x, y : array-like, shape (n, )
  5548. Input values
  5549. bins : None or int or [int, int] or array-like or [array, array]
  5550. The bin specification:
  5551. - If int, the number of bins for the two dimensions
  5552. (nx=ny=bins).
  5553. - If ``[int, int]``, the number of bins in each dimension
  5554. (nx, ny = bins).
  5555. - If array-like, the bin edges for the two dimensions
  5556. (x_edges=y_edges=bins).
  5557. - If ``[array, array]``, the bin edges in each dimension
  5558. (x_edges, y_edges = bins).
  5559. The default value is 10.
  5560. range : array-like shape(2, 2), optional, default: None
  5561. The leftmost and rightmost edges of the bins along each dimension
  5562. (if not specified explicitly in the bins parameters): ``[[xmin,
  5563. xmax], [ymin, ymax]]``. All values outside of this range will be
  5564. considered outliers and not tallied in the histogram.
  5565. density : bool, optional, default: False
  5566. Normalize histogram. *normed* is a deprecated synonym for this
  5567. parameter.
  5568. weights : array-like, shape (n, ), optional, default: None
  5569. An array of values w_i weighing each sample (x_i, y_i).
  5570. cmin : scalar, optional, default: None
  5571. All bins that has count less than cmin will not be displayed (set
  5572. to NaN before passing to imshow) and these count values in the
  5573. return value count histogram will also be set to nan upon return.
  5574. cmax : scalar, optional, default: None
  5575. All bins that has count more than cmax will not be displayed (set
  5576. to NaN before passing to imshow) and these count values in the
  5577. return value count histogram will also be set to nan upon return.
  5578. Returns
  5579. -------
  5580. h : 2D array
  5581. The bi-dimensional histogram of samples x and y. Values in x are
  5582. histogrammed along the first dimension and values in y are
  5583. histogrammed along the second dimension.
  5584. xedges : 1D array
  5585. The bin edges along the x axis.
  5586. yedges : 1D array
  5587. The bin edges along the y axis.
  5588. image : `~.matplotlib.collections.QuadMesh`
  5589. Other Parameters
  5590. ----------------
  5591. cmap : Colormap or str, optional
  5592. A `.colors.Colormap` instance. If not set, use rc settings.
  5593. norm : Normalize, optional
  5594. A `.colors.Normalize` instance is used to
  5595. scale luminance data to ``[0, 1]``. If not set, defaults to
  5596. `.colors.Normalize()`.
  5597. vmin/vmax : None or scalar, optional
  5598. Arguments passed to the `~.colors.Normalize` instance.
  5599. alpha : ``0 <= scalar <= 1`` or ``None``, optional
  5600. The alpha blending value.
  5601. See also
  5602. --------
  5603. hist : 1D histogram plotting
  5604. Notes
  5605. -----
  5606. - Currently ``hist2d`` calculates its own axis limits, and any limits
  5607. previously set are ignored.
  5608. - Rendering the histogram with a logarithmic color scale is
  5609. accomplished by passing a `.colors.LogNorm` instance to the *norm*
  5610. keyword argument. Likewise, power-law normalization (similar
  5611. in effect to gamma correction) can be accomplished with
  5612. `.colors.PowerNorm`.
  5613. """
  5614. h, xedges, yedges = np.histogram2d(x, y, bins=bins, range=range,
  5615. normed=density, weights=weights)
  5616. if cmin is not None:
  5617. h[h < cmin] = None
  5618. if cmax is not None:
  5619. h[h > cmax] = None
  5620. pc = self.pcolormesh(xedges, yedges, h.T, **kwargs)
  5621. self.set_xlim(xedges[0], xedges[-1])
  5622. self.set_ylim(yedges[0], yedges[-1])
  5623. return h, xedges, yedges, pc
  5624. @_preprocess_data(replace_names=["x"])
  5625. @docstring.dedent_interpd
  5626. def psd(self, x, NFFT=None, Fs=None, Fc=None, detrend=None,
  5627. window=None, noverlap=None, pad_to=None,
  5628. sides=None, scale_by_freq=None, return_line=None, **kwargs):
  5629. r"""
  5630. Plot the power spectral density.
  5631. The power spectral density :math:`P_{xx}` by Welch's average
  5632. periodogram method. The vector *x* is divided into *NFFT* length
  5633. segments. Each segment is detrended by function *detrend* and
  5634. windowed by function *window*. *noverlap* gives the length of
  5635. the overlap between segments. The :math:`|\mathrm{fft}(i)|^2`
  5636. of each segment :math:`i` are averaged to compute :math:`P_{xx}`,
  5637. with a scaling to correct for power loss due to windowing.
  5638. If len(*x*) < *NFFT*, it will be zero padded to *NFFT*.
  5639. Parameters
  5640. ----------
  5641. x : 1-D array or sequence
  5642. Array or sequence containing the data
  5643. %(Spectral)s
  5644. %(PSD)s
  5645. noverlap : int
  5646. The number of points of overlap between segments.
  5647. The default value is 0 (no overlap).
  5648. Fc : int
  5649. The center frequency of *x* (defaults to 0), which offsets
  5650. the x extents of the plot to reflect the frequency range used
  5651. when a signal is acquired and then filtered and downsampled to
  5652. baseband.
  5653. return_line : bool
  5654. Whether to include the line object plotted in the returned values.
  5655. Default is False.
  5656. Returns
  5657. -------
  5658. Pxx : 1-D array
  5659. The values for the power spectrum `P_{xx}` before scaling
  5660. (real valued).
  5661. freqs : 1-D array
  5662. The frequencies corresponding to the elements in *Pxx*.
  5663. line : `~matplotlib.lines.Line2D`
  5664. The line created by this function.
  5665. Only returned if *return_line* is True.
  5666. Other Parameters
  5667. ----------------
  5668. **kwargs
  5669. Keyword arguments control the `.Line2D` properties:
  5670. %(_Line2D_docstr)s
  5671. See Also
  5672. --------
  5673. :func:`specgram`
  5674. :func:`specgram` differs in the default overlap; in not returning
  5675. the mean of the segment periodograms; in returning the times of the
  5676. segments; and in plotting a colormap instead of a line.
  5677. :func:`magnitude_spectrum`
  5678. :func:`magnitude_spectrum` plots the magnitude spectrum.
  5679. :func:`csd`
  5680. :func:`csd` plots the spectral density between two signals.
  5681. Notes
  5682. -----
  5683. For plotting, the power is plotted as
  5684. :math:`10\log_{10}(P_{xx})` for decibels, though *Pxx* itself
  5685. is returned.
  5686. References
  5687. ----------
  5688. Bendat & Piersol -- Random Data: Analysis and Measurement Procedures,
  5689. John Wiley & Sons (1986)
  5690. """
  5691. if Fc is None:
  5692. Fc = 0
  5693. pxx, freqs = mlab.psd(x=x, NFFT=NFFT, Fs=Fs, detrend=detrend,
  5694. window=window, noverlap=noverlap, pad_to=pad_to,
  5695. sides=sides, scale_by_freq=scale_by_freq)
  5696. freqs += Fc
  5697. if scale_by_freq in (None, True):
  5698. psd_units = 'dB/Hz'
  5699. else:
  5700. psd_units = 'dB'
  5701. line = self.plot(freqs, 10 * np.log10(pxx), **kwargs)
  5702. self.set_xlabel('Frequency')
  5703. self.set_ylabel('Power Spectral Density (%s)' % psd_units)
  5704. self.grid(True)
  5705. vmin, vmax = self.viewLim.intervaly
  5706. intv = vmax - vmin
  5707. logi = int(np.log10(intv))
  5708. if logi == 0:
  5709. logi = .1
  5710. step = 10 * logi
  5711. ticks = np.arange(math.floor(vmin), math.ceil(vmax) + 1, step)
  5712. self.set_yticks(ticks)
  5713. if return_line is None or not return_line:
  5714. return pxx, freqs
  5715. else:
  5716. return pxx, freqs, line
  5717. @_preprocess_data(replace_names=["x", "y"], label_namer="y")
  5718. @docstring.dedent_interpd
  5719. def csd(self, x, y, NFFT=None, Fs=None, Fc=None, detrend=None,
  5720. window=None, noverlap=None, pad_to=None,
  5721. sides=None, scale_by_freq=None, return_line=None, **kwargs):
  5722. r"""
  5723. Plot the cross-spectral density.
  5724. The cross spectral density :math:`P_{xy}` by Welch's average
  5725. periodogram method. The vectors *x* and *y* are divided into
  5726. *NFFT* length segments. Each segment is detrended by function
  5727. *detrend* and windowed by function *window*. *noverlap* gives
  5728. the length of the overlap between segments. The product of
  5729. the direct FFTs of *x* and *y* are averaged over each segment
  5730. to compute :math:`P_{xy}`, with a scaling to correct for power
  5731. loss due to windowing.
  5732. If len(*x*) < *NFFT* or len(*y*) < *NFFT*, they will be zero
  5733. padded to *NFFT*.
  5734. Parameters
  5735. ----------
  5736. x, y : 1-D arrays or sequences
  5737. Arrays or sequences containing the data.
  5738. %(Spectral)s
  5739. %(PSD)s
  5740. noverlap : int
  5741. The number of points of overlap between segments.
  5742. The default value is 0 (no overlap).
  5743. Fc : int
  5744. The center frequency of *x* (defaults to 0), which offsets
  5745. the x extents of the plot to reflect the frequency range used
  5746. when a signal is acquired and then filtered and downsampled to
  5747. baseband.
  5748. return_line : bool
  5749. Whether to include the line object plotted in the returned values.
  5750. Default is False.
  5751. Returns
  5752. -------
  5753. Pxy : 1-D array
  5754. The values for the cross spectrum `P_{xy}` before scaling
  5755. (complex valued).
  5756. freqs : 1-D array
  5757. The frequencies corresponding to the elements in *Pxy*.
  5758. line : `~matplotlib.lines.Line2D`
  5759. The line created by this function.
  5760. Only returned if *return_line* is True.
  5761. Other Parameters
  5762. ----------------
  5763. **kwargs
  5764. Keyword arguments control the `.Line2D` properties:
  5765. %(_Line2D_docstr)s
  5766. See Also
  5767. --------
  5768. :func:`psd`
  5769. :func:`psd` is the equivalent to setting y=x.
  5770. Notes
  5771. -----
  5772. For plotting, the power is plotted as
  5773. :math:`10 \log_{10}(P_{xy})` for decibels, though `P_{xy}` itself
  5774. is returned.
  5775. References
  5776. ----------
  5777. Bendat & Piersol -- Random Data: Analysis and Measurement Procedures,
  5778. John Wiley & Sons (1986)
  5779. """
  5780. if Fc is None:
  5781. Fc = 0
  5782. pxy, freqs = mlab.csd(x=x, y=y, NFFT=NFFT, Fs=Fs, detrend=detrend,
  5783. window=window, noverlap=noverlap, pad_to=pad_to,
  5784. sides=sides, scale_by_freq=scale_by_freq)
  5785. # pxy is complex
  5786. freqs += Fc
  5787. line = self.plot(freqs, 10 * np.log10(np.abs(pxy)), **kwargs)
  5788. self.set_xlabel('Frequency')
  5789. self.set_ylabel('Cross Spectrum Magnitude (dB)')
  5790. self.grid(True)
  5791. vmin, vmax = self.viewLim.intervaly
  5792. intv = vmax - vmin
  5793. step = 10 * int(np.log10(intv))
  5794. ticks = np.arange(math.floor(vmin), math.ceil(vmax) + 1, step)
  5795. self.set_yticks(ticks)
  5796. if return_line is None or not return_line:
  5797. return pxy, freqs
  5798. else:
  5799. return pxy, freqs, line
  5800. @_preprocess_data(replace_names=["x"])
  5801. @docstring.dedent_interpd
  5802. def magnitude_spectrum(self, x, Fs=None, Fc=None, window=None,
  5803. pad_to=None, sides=None, scale=None,
  5804. **kwargs):
  5805. """
  5806. Plot the magnitude spectrum.
  5807. Compute the magnitude spectrum of *x*. Data is padded to a
  5808. length of *pad_to* and the windowing function *window* is applied to
  5809. the signal.
  5810. Parameters
  5811. ----------
  5812. x : 1-D array or sequence
  5813. Array or sequence containing the data.
  5814. %(Spectral)s
  5815. %(Single_Spectrum)s
  5816. scale : {'default', 'linear', 'dB'}
  5817. The scaling of the values in the *spec*. 'linear' is no scaling.
  5818. 'dB' returns the values in dB scale, i.e., the dB amplitude
  5819. (20 * log10). 'default' is 'linear'.
  5820. Fc : int
  5821. The center frequency of *x* (defaults to 0), which offsets
  5822. the x extents of the plot to reflect the frequency range used
  5823. when a signal is acquired and then filtered and downsampled to
  5824. baseband.
  5825. Returns
  5826. -------
  5827. spectrum : 1-D array
  5828. The values for the magnitude spectrum before scaling (real valued).
  5829. freqs : 1-D array
  5830. The frequencies corresponding to the elements in *spectrum*.
  5831. line : `~matplotlib.lines.Line2D`
  5832. The line created by this function.
  5833. Other Parameters
  5834. ----------------
  5835. **kwargs
  5836. Keyword arguments control the `.Line2D` properties:
  5837. %(_Line2D_docstr)s
  5838. See Also
  5839. --------
  5840. :func:`psd`
  5841. :func:`psd` plots the power spectral density.`.
  5842. :func:`angle_spectrum`
  5843. :func:`angle_spectrum` plots the angles of the corresponding
  5844. frequencies.
  5845. :func:`phase_spectrum`
  5846. :func:`phase_spectrum` plots the phase (unwrapped angle) of the
  5847. corresponding frequencies.
  5848. :func:`specgram`
  5849. :func:`specgram` can plot the magnitude spectrum of segments within
  5850. the signal in a colormap.
  5851. """
  5852. if Fc is None:
  5853. Fc = 0
  5854. if scale is None or scale == 'default':
  5855. scale = 'linear'
  5856. spec, freqs = mlab.magnitude_spectrum(x=x, Fs=Fs, window=window,
  5857. pad_to=pad_to, sides=sides)
  5858. freqs += Fc
  5859. if scale == 'linear':
  5860. Z = spec
  5861. yunits = 'energy'
  5862. elif scale == 'dB':
  5863. Z = 20. * np.log10(spec)
  5864. yunits = 'dB'
  5865. else:
  5866. raise ValueError('Unknown scale %s', scale)
  5867. lines = self.plot(freqs, Z, **kwargs)
  5868. self.set_xlabel('Frequency')
  5869. self.set_ylabel('Magnitude (%s)' % yunits)
  5870. return spec, freqs, lines[0]
  5871. @_preprocess_data(replace_names=["x"])
  5872. @docstring.dedent_interpd
  5873. def angle_spectrum(self, x, Fs=None, Fc=None, window=None,
  5874. pad_to=None, sides=None, **kwargs):
  5875. """
  5876. Plot the angle spectrum.
  5877. Compute the angle spectrum (wrapped phase spectrum) of *x*.
  5878. Data is padded to a length of *pad_to* and the windowing function
  5879. *window* is applied to the signal.
  5880. Parameters
  5881. ----------
  5882. x : 1-D array or sequence
  5883. Array or sequence containing the data.
  5884. %(Spectral)s
  5885. %(Single_Spectrum)s
  5886. Fc : int
  5887. The center frequency of *x* (defaults to 0), which offsets
  5888. the x extents of the plot to reflect the frequency range used
  5889. when a signal is acquired and then filtered and downsampled to
  5890. baseband.
  5891. Returns
  5892. -------
  5893. spectrum : 1-D array
  5894. The values for the angle spectrum in radians (real valued).
  5895. freqs : 1-D array
  5896. The frequencies corresponding to the elements in *spectrum*.
  5897. line : `~matplotlib.lines.Line2D`
  5898. The line created by this function.
  5899. Other Parameters
  5900. ----------------
  5901. **kwargs
  5902. Keyword arguments control the `.Line2D` properties:
  5903. %(_Line2D_docstr)s
  5904. See Also
  5905. --------
  5906. :func:`magnitude_spectrum`
  5907. :func:`angle_spectrum` plots the magnitudes of the corresponding
  5908. frequencies.
  5909. :func:`phase_spectrum`
  5910. :func:`phase_spectrum` plots the unwrapped version of this
  5911. function.
  5912. :func:`specgram`
  5913. :func:`specgram` can plot the angle spectrum of segments within the
  5914. signal in a colormap.
  5915. """
  5916. if Fc is None:
  5917. Fc = 0
  5918. spec, freqs = mlab.angle_spectrum(x=x, Fs=Fs, window=window,
  5919. pad_to=pad_to, sides=sides)
  5920. freqs += Fc
  5921. lines = self.plot(freqs, spec, **kwargs)
  5922. self.set_xlabel('Frequency')
  5923. self.set_ylabel('Angle (radians)')
  5924. return spec, freqs, lines[0]
  5925. @_preprocess_data(replace_names=["x"])
  5926. @docstring.dedent_interpd
  5927. def phase_spectrum(self, x, Fs=None, Fc=None, window=None,
  5928. pad_to=None, sides=None, **kwargs):
  5929. """
  5930. Plot the phase spectrum.
  5931. Compute the phase spectrum (unwrapped angle spectrum) of *x*.
  5932. Data is padded to a length of *pad_to* and the windowing function
  5933. *window* is applied to the signal.
  5934. Parameters
  5935. ----------
  5936. x : 1-D array or sequence
  5937. Array or sequence containing the data
  5938. %(Spectral)s
  5939. %(Single_Spectrum)s
  5940. Fc : int
  5941. The center frequency of *x* (defaults to 0), which offsets
  5942. the x extents of the plot to reflect the frequency range used
  5943. when a signal is acquired and then filtered and downsampled to
  5944. baseband.
  5945. Returns
  5946. -------
  5947. spectrum : 1-D array
  5948. The values for the phase spectrum in radians (real valued).
  5949. freqs : 1-D array
  5950. The frequencies corresponding to the elements in *spectrum*.
  5951. line : `~matplotlib.lines.Line2D`
  5952. The line created by this function.
  5953. Other Parameters
  5954. ----------------
  5955. **kwargs
  5956. Keyword arguments control the `.Line2D` properties:
  5957. %(_Line2D_docstr)s
  5958. See Also
  5959. --------
  5960. :func:`magnitude_spectrum`
  5961. :func:`magnitude_spectrum` plots the magnitudes of the
  5962. corresponding frequencies.
  5963. :func:`angle_spectrum`
  5964. :func:`angle_spectrum` plots the wrapped version of this function.
  5965. :func:`specgram`
  5966. :func:`specgram` can plot the phase spectrum of segments within the
  5967. signal in a colormap.
  5968. """
  5969. if Fc is None:
  5970. Fc = 0
  5971. spec, freqs = mlab.phase_spectrum(x=x, Fs=Fs, window=window,
  5972. pad_to=pad_to, sides=sides)
  5973. freqs += Fc
  5974. lines = self.plot(freqs, spec, **kwargs)
  5975. self.set_xlabel('Frequency')
  5976. self.set_ylabel('Phase (radians)')
  5977. return spec, freqs, lines[0]
  5978. @_preprocess_data(replace_names=["x", "y"])
  5979. @docstring.dedent_interpd
  5980. def cohere(self, x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none,
  5981. window=mlab.window_hanning, noverlap=0, pad_to=None,
  5982. sides='default', scale_by_freq=None, **kwargs):
  5983. r"""
  5984. Plot the coherence between *x* and *y*.
  5985. Plot the coherence between *x* and *y*. Coherence is the
  5986. normalized cross spectral density:
  5987. .. math::
  5988. C_{xy} = \frac{|P_{xy}|^2}{P_{xx}P_{yy}}
  5989. Parameters
  5990. ----------
  5991. %(Spectral)s
  5992. %(PSD)s
  5993. noverlap : int
  5994. The number of points of overlap between blocks. The
  5995. default value is 0 (no overlap).
  5996. Fc : int
  5997. The center frequency of *x* (defaults to 0), which offsets
  5998. the x extents of the plot to reflect the frequency range used
  5999. when a signal is acquired and then filtered and downsampled to
  6000. baseband.
  6001. Returns
  6002. -------
  6003. Cxy : 1-D array
  6004. The coherence vector.
  6005. freqs : 1-D array
  6006. The frequencies for the elements in *Cxy*.
  6007. Other Parameters
  6008. ----------------
  6009. **kwargs
  6010. Keyword arguments control the `.Line2D` properties:
  6011. %(_Line2D_docstr)s
  6012. References
  6013. ----------
  6014. Bendat & Piersol -- Random Data: Analysis and Measurement Procedures,
  6015. John Wiley & Sons (1986)
  6016. """
  6017. cxy, freqs = mlab.cohere(x=x, y=y, NFFT=NFFT, Fs=Fs, detrend=detrend,
  6018. window=window, noverlap=noverlap,
  6019. scale_by_freq=scale_by_freq)
  6020. freqs += Fc
  6021. self.plot(freqs, cxy, **kwargs)
  6022. self.set_xlabel('Frequency')
  6023. self.set_ylabel('Coherence')
  6024. self.grid(True)
  6025. return cxy, freqs
  6026. @_preprocess_data(replace_names=["x"])
  6027. @docstring.dedent_interpd
  6028. def specgram(self, x, NFFT=None, Fs=None, Fc=None, detrend=None,
  6029. window=None, noverlap=None,
  6030. cmap=None, xextent=None, pad_to=None, sides=None,
  6031. scale_by_freq=None, mode=None, scale=None,
  6032. vmin=None, vmax=None, **kwargs):
  6033. """
  6034. Plot a spectrogram.
  6035. Compute and plot a spectrogram of data in *x*. Data are split into
  6036. *NFFT* length segments and the spectrum of each section is
  6037. computed. The windowing function *window* is applied to each
  6038. segment, and the amount of overlap of each segment is
  6039. specified with *noverlap*. The spectrogram is plotted as a colormap
  6040. (using imshow).
  6041. Parameters
  6042. ----------
  6043. x : 1-D array or sequence
  6044. Array or sequence containing the data.
  6045. %(Spectral)s
  6046. %(PSD)s
  6047. mode : {'default', 'psd', 'magnitude', 'angle', 'phase'}
  6048. What sort of spectrum to use. Default is 'psd', which takes the
  6049. power spectral density. 'magnitude' returns the magnitude
  6050. spectrum. 'angle' returns the phase spectrum without unwrapping.
  6051. 'phase' returns the phase spectrum with unwrapping.
  6052. noverlap : int
  6053. The number of points of overlap between blocks. The
  6054. default value is 128.
  6055. scale : {'default', 'linear', 'dB'}
  6056. The scaling of the values in the *spec*. 'linear' is no scaling.
  6057. 'dB' returns the values in dB scale. When *mode* is 'psd',
  6058. this is dB power (10 * log10). Otherwise this is dB amplitude
  6059. (20 * log10). 'default' is 'dB' if *mode* is 'psd' or
  6060. 'magnitude' and 'linear' otherwise. This must be 'linear'
  6061. if *mode* is 'angle' or 'phase'.
  6062. Fc : int
  6063. The center frequency of *x* (defaults to 0), which offsets
  6064. the x extents of the plot to reflect the frequency range used
  6065. when a signal is acquired and then filtered and downsampled to
  6066. baseband.
  6067. cmap
  6068. A :class:`matplotlib.colors.Colormap` instance; if *None*, use
  6069. default determined by rc
  6070. xextent : *None* or (xmin, xmax)
  6071. The image extent along the x-axis. The default sets *xmin* to the
  6072. left border of the first bin (*spectrum* column) and *xmax* to the
  6073. right border of the last bin. Note that for *noverlap>0* the width
  6074. of the bins is smaller than those of the segments.
  6075. **kwargs
  6076. Additional keyword arguments are passed on to imshow which makes
  6077. the specgram image.
  6078. Returns
  6079. -------
  6080. spectrum : 2-D array
  6081. Columns are the periodograms of successive segments.
  6082. freqs : 1-D array
  6083. The frequencies corresponding to the rows in *spectrum*.
  6084. t : 1-D array
  6085. The times corresponding to midpoints of segments (i.e., the columns
  6086. in *spectrum*).
  6087. im : instance of class :class:`~matplotlib.image.AxesImage`
  6088. The image created by imshow containing the spectrogram
  6089. See Also
  6090. --------
  6091. :func:`psd`
  6092. :func:`psd` differs in the default overlap; in returning the mean
  6093. of the segment periodograms; in not returning times; and in
  6094. generating a line plot instead of colormap.
  6095. :func:`magnitude_spectrum`
  6096. A single spectrum, similar to having a single segment when *mode*
  6097. is 'magnitude'. Plots a line instead of a colormap.
  6098. :func:`angle_spectrum`
  6099. A single spectrum, similar to having a single segment when *mode*
  6100. is 'angle'. Plots a line instead of a colormap.
  6101. :func:`phase_spectrum`
  6102. A single spectrum, similar to having a single segment when *mode*
  6103. is 'phase'. Plots a line instead of a colormap.
  6104. Notes
  6105. -----
  6106. The parameters *detrend* and *scale_by_freq* do only apply when *mode*
  6107. is set to 'psd'.
  6108. """
  6109. if NFFT is None:
  6110. NFFT = 256 # same default as in mlab.specgram()
  6111. if Fc is None:
  6112. Fc = 0 # same default as in mlab._spectral_helper()
  6113. if noverlap is None:
  6114. noverlap = 128 # same default as in mlab.specgram()
  6115. if mode == 'complex':
  6116. raise ValueError('Cannot plot a complex specgram')
  6117. if scale is None or scale == 'default':
  6118. if mode in ['angle', 'phase']:
  6119. scale = 'linear'
  6120. else:
  6121. scale = 'dB'
  6122. elif mode in ['angle', 'phase'] and scale == 'dB':
  6123. raise ValueError('Cannot use dB scale with angle or phase mode')
  6124. spec, freqs, t = mlab.specgram(x=x, NFFT=NFFT, Fs=Fs,
  6125. detrend=detrend, window=window,
  6126. noverlap=noverlap, pad_to=pad_to,
  6127. sides=sides,
  6128. scale_by_freq=scale_by_freq,
  6129. mode=mode)
  6130. if scale == 'linear':
  6131. Z = spec
  6132. elif scale == 'dB':
  6133. if mode is None or mode == 'default' or mode == 'psd':
  6134. Z = 10. * np.log10(spec)
  6135. else:
  6136. Z = 20. * np.log10(spec)
  6137. else:
  6138. raise ValueError('Unknown scale %s', scale)
  6139. Z = np.flipud(Z)
  6140. if xextent is None:
  6141. # padding is needed for first and last segment:
  6142. pad_xextent = (NFFT-noverlap) / Fs / 2
  6143. xextent = np.min(t) - pad_xextent, np.max(t) + pad_xextent
  6144. xmin, xmax = xextent
  6145. freqs += Fc
  6146. extent = xmin, xmax, freqs[0], freqs[-1]
  6147. im = self.imshow(Z, cmap, extent=extent, vmin=vmin, vmax=vmax,
  6148. **kwargs)
  6149. self.axis('auto')
  6150. return spec, freqs, t, im
  6151. @docstring.dedent_interpd
  6152. def spy(self, Z, precision=0, marker=None, markersize=None,
  6153. aspect='equal', origin="upper", **kwargs):
  6154. """
  6155. Plot the sparsity pattern of a 2D array.
  6156. This visualizes the non-zero values of the array.
  6157. Two plotting styles are available: image and marker. Both
  6158. are available for full arrays, but only the marker style
  6159. works for `scipy.sparse.spmatrix` instances.
  6160. **Image style**
  6161. If *marker* and *markersize* are *None*, `~.Axes.imshow` is used. Any
  6162. extra remaining keyword arguments are passed to this method.
  6163. **Marker style**
  6164. If *Z* is a `scipy.sparse.spmatrix` or *marker* or *markersize* are
  6165. *None*, a `.Line2D` object will be returned with the value of marker
  6166. determining the marker type, and any remaining keyword arguments
  6167. passed to `~.Axes.plot`.
  6168. Parameters
  6169. ----------
  6170. Z : array-like (M, N)
  6171. The array to be plotted.
  6172. precision : float or 'present', optional, default: 0
  6173. If *precision* is 0, any non-zero value will be plotted. Otherwise,
  6174. values of :math:`|Z| > precision` will be plotted.
  6175. For :class:`scipy.sparse.spmatrix` instances, you can also
  6176. pass 'present'. In this case any value present in the array
  6177. will be plotted, even if it is identically zero.
  6178. origin : {'upper', 'lower'}, optional
  6179. Place the [0, 0] index of the array in the upper left or lower left
  6180. corner of the axes. The convention 'upper' is typically used for
  6181. matrices and images.
  6182. If not given, :rc:`image.origin` is used, defaulting to 'upper'.
  6183. aspect : {'equal', 'auto', None} or float, optional
  6184. Controls the aspect ratio of the axes. The aspect is of particular
  6185. relevance for images since it may distort the image, i.e. pixel
  6186. will not be square.
  6187. This parameter is a shortcut for explicitly calling
  6188. `.Axes.set_aspect`. See there for further details.
  6189. - 'equal': Ensures an aspect ratio of 1. Pixels will be square.
  6190. - 'auto': The axes is kept fixed and the aspect is adjusted so
  6191. that the data fit in the axes. In general, this will result in
  6192. non-square pixels.
  6193. - *None*: Use :rc:`image.aspect`.
  6194. Default: 'equal'
  6195. Returns
  6196. -------
  6197. ret : `~matplotlib.image.AxesImage` or `.Line2D`
  6198. The return type depends on the plotting style (see above).
  6199. Other Parameters
  6200. ----------------
  6201. **kwargs
  6202. The supported additional parameters depend on the plotting style.
  6203. For the image style, you can pass the following additional
  6204. parameters of `~.Axes.imshow`:
  6205. - *cmap*
  6206. - *alpha*
  6207. - *url*
  6208. - any `.Artist` properties (passed on to the `.AxesImage`)
  6209. For the marker style, you can pass any `.Line2D` property except
  6210. for *linestyle*:
  6211. %(_Line2D_docstr)s
  6212. """
  6213. if marker is None and markersize is None and hasattr(Z, 'tocoo'):
  6214. marker = 's'
  6215. if marker is None and markersize is None:
  6216. Z = np.asarray(Z)
  6217. mask = np.abs(Z) > precision
  6218. if 'cmap' not in kwargs:
  6219. kwargs['cmap'] = mcolors.ListedColormap(['w', 'k'],
  6220. name='binary')
  6221. if 'interpolation' in kwargs:
  6222. raise TypeError(
  6223. "spy() got an unexpected keyword argument 'interpolation'")
  6224. ret = self.imshow(mask, interpolation='nearest', aspect=aspect,
  6225. origin=origin, **kwargs)
  6226. else:
  6227. if hasattr(Z, 'tocoo'):
  6228. c = Z.tocoo()
  6229. if precision == 'present':
  6230. y = c.row
  6231. x = c.col
  6232. else:
  6233. nonzero = np.abs(c.data) > precision
  6234. y = c.row[nonzero]
  6235. x = c.col[nonzero]
  6236. else:
  6237. Z = np.asarray(Z)
  6238. nonzero = np.abs(Z) > precision
  6239. y, x = np.nonzero(nonzero)
  6240. if marker is None:
  6241. marker = 's'
  6242. if markersize is None:
  6243. markersize = 10
  6244. if 'linestyle' in kwargs:
  6245. raise TypeError(
  6246. "spy() got an unexpected keyword argument 'linestyle'")
  6247. marks = mlines.Line2D(x, y, linestyle='None',
  6248. marker=marker, markersize=markersize, **kwargs)
  6249. self.add_line(marks)
  6250. nr, nc = Z.shape
  6251. self.set_xlim(-0.5, nc - 0.5)
  6252. self.set_ylim(nr - 0.5, -0.5)
  6253. self.set_aspect(aspect)
  6254. ret = marks
  6255. self.title.set_y(1.05)
  6256. self.xaxis.tick_top()
  6257. self.xaxis.set_ticks_position('both')
  6258. self.xaxis.set_major_locator(mticker.MaxNLocator(nbins=9,
  6259. steps=[1, 2, 5, 10],
  6260. integer=True))
  6261. self.yaxis.set_major_locator(mticker.MaxNLocator(nbins=9,
  6262. steps=[1, 2, 5, 10],
  6263. integer=True))
  6264. return ret
  6265. def matshow(self, Z, **kwargs):
  6266. """
  6267. Plot the values of a 2D matrix or array as color-coded image.
  6268. The matrix will be shown the way it would be printed, with the first
  6269. row at the top. Row and column numbering is zero-based.
  6270. Parameters
  6271. ----------
  6272. Z : array-like(M, N)
  6273. The matrix to be displayed.
  6274. Returns
  6275. -------
  6276. image : `~matplotlib.image.AxesImage`
  6277. Other Parameters
  6278. ----------------
  6279. **kwargs : `~matplotlib.axes.Axes.imshow` arguments
  6280. See Also
  6281. --------
  6282. imshow : More general function to plot data on a 2D regular raster.
  6283. Notes
  6284. -----
  6285. This is just a convenience function wrapping `.imshow` to set useful
  6286. defaults for displaying a matrix. In particular:
  6287. - Set ``origin='upper'``.
  6288. - Set ``interpolation='nearest'``.
  6289. - Set ``aspect='equal'``.
  6290. - Ticks are placed to the left and above.
  6291. - Ticks are formatted to show integer indices.
  6292. """
  6293. Z = np.asanyarray(Z)
  6294. kw = {'origin': 'upper',
  6295. 'interpolation': 'nearest',
  6296. 'aspect': 'equal', # (already the imshow default)
  6297. **kwargs}
  6298. im = self.imshow(Z, **kw)
  6299. self.title.set_y(1.05)
  6300. self.xaxis.tick_top()
  6301. self.xaxis.set_ticks_position('both')
  6302. self.xaxis.set_major_locator(mticker.MaxNLocator(nbins=9,
  6303. steps=[1, 2, 5, 10],
  6304. integer=True))
  6305. self.yaxis.set_major_locator(mticker.MaxNLocator(nbins=9,
  6306. steps=[1, 2, 5, 10],
  6307. integer=True))
  6308. return im
  6309. @_preprocess_data(replace_names=["dataset"])
  6310. def violinplot(self, dataset, positions=None, vert=True, widths=0.5,
  6311. showmeans=False, showextrema=True, showmedians=False,
  6312. quantiles=None, points=100, bw_method=None):
  6313. """
  6314. Make a violin plot.
  6315. Make a violin plot for each column of *dataset* or each vector in
  6316. sequence *dataset*. Each filled area extends to represent the
  6317. entire data range, with optional lines at the mean, the median,
  6318. the minimum, the maximum, and user-specified quantiles.
  6319. Parameters
  6320. ----------
  6321. dataset : Array or a sequence of vectors.
  6322. The input data.
  6323. positions : array-like, default = [1, 2, ..., n]
  6324. Sets the positions of the violins. The ticks and limits are
  6325. automatically set to match the positions.
  6326. vert : bool, default = True.
  6327. If true, creates a vertical violin plot.
  6328. Otherwise, creates a horizontal violin plot.
  6329. widths : array-like, default = 0.5
  6330. Either a scalar or a vector that sets the maximal width of
  6331. each violin. The default is 0.5, which uses about half of the
  6332. available horizontal space.
  6333. showmeans : bool, default = False
  6334. If `True`, will toggle rendering of the means.
  6335. showextrema : bool, default = True
  6336. If `True`, will toggle rendering of the extrema.
  6337. showmedians : bool, default = False
  6338. If `True`, will toggle rendering of the medians.
  6339. quantiles : array-like, default = None
  6340. If not None, set a list of floats in interval [0, 1] for each violin,
  6341. which stands for the quantiles that will be rendered for that
  6342. violin.
  6343. points : scalar, default = 100
  6344. Defines the number of points to evaluate each of the
  6345. gaussian kernel density estimations at.
  6346. bw_method : str, scalar or callable, optional
  6347. The method used to calculate the estimator bandwidth. This can be
  6348. 'scott', 'silverman', a scalar constant or a callable. If a
  6349. scalar, this will be used directly as `kde.factor`. If a
  6350. callable, it should take a `GaussianKDE` instance as its only
  6351. parameter and return a scalar. If None (default), 'scott' is used.
  6352. Returns
  6353. -------
  6354. result : dict
  6355. A dictionary mapping each component of the violinplot to a
  6356. list of the corresponding collection instances created. The
  6357. dictionary has the following keys:
  6358. - ``bodies``: A list of the `~.collections.PolyCollection`
  6359. instances containing the filled area of each violin.
  6360. - ``cmeans``: A `~.collections.LineCollection` instance that marks
  6361. the mean values of each of the violin's distribution.
  6362. - ``cmins``: A `~.collections.LineCollection` instance that marks
  6363. the bottom of each violin's distribution.
  6364. - ``cmaxes``: A `~.collections.LineCollection` instance that marks
  6365. the top of each violin's distribution.
  6366. - ``cbars``: A `~.collections.LineCollection` instance that marks
  6367. the centers of each violin's distribution.
  6368. - ``cmedians``: A `~.collections.LineCollection` instance that
  6369. marks the median values of each of the violin's distribution.
  6370. - ``cquantiles``: A `~.collections.LineCollection` instance created
  6371. to identify the quantile values of each of the violin's
  6372. distribution.
  6373. """
  6374. def _kde_method(X, coords):
  6375. # fallback gracefully if the vector contains only one value
  6376. if np.all(X[0] == X):
  6377. return (X[0] == coords).astype(float)
  6378. kde = mlab.GaussianKDE(X, bw_method)
  6379. return kde.evaluate(coords)
  6380. vpstats = cbook.violin_stats(dataset, _kde_method, points=points,
  6381. quantiles=quantiles)
  6382. return self.violin(vpstats, positions=positions, vert=vert,
  6383. widths=widths, showmeans=showmeans,
  6384. showextrema=showextrema, showmedians=showmedians)
  6385. def violin(self, vpstats, positions=None, vert=True, widths=0.5,
  6386. showmeans=False, showextrema=True, showmedians=False):
  6387. """Drawing function for violin plots.
  6388. Draw a violin plot for each column of *vpstats*. Each filled area
  6389. extends to represent the entire data range, with optional lines at the
  6390. mean, the median, the minimum, the maximum, and the quantiles values.
  6391. Parameters
  6392. ----------
  6393. vpstats : list of dicts
  6394. A list of dictionaries containing stats for each violin plot.
  6395. Required keys are:
  6396. - ``coords``: A list of scalars containing the coordinates that
  6397. the violin's kernel density estimate were evaluated at.
  6398. - ``vals``: A list of scalars containing the values of the
  6399. kernel density estimate at each of the coordinates given
  6400. in *coords*.
  6401. - ``mean``: The mean value for this violin's dataset.
  6402. - ``median``: The median value for this violin's dataset.
  6403. - ``min``: The minimum value for this violin's dataset.
  6404. - ``max``: The maximum value for this violin's dataset.
  6405. Optional keys are:
  6406. - ``quantiles``: A list of scalars containing the quantile values
  6407. for this violin's dataset.
  6408. positions : array-like, default = [1, 2, ..., n]
  6409. Sets the positions of the violins. The ticks and limits are
  6410. automatically set to match the positions.
  6411. vert : bool, default = True.
  6412. If true, plots the violins vertically.
  6413. Otherwise, plots the violins horizontally.
  6414. widths : array-like, default = 0.5
  6415. Either a scalar or a vector that sets the maximal width of
  6416. each violin. The default is 0.5, which uses about half of the
  6417. available horizontal space.
  6418. showmeans : bool, default = False
  6419. If true, will toggle rendering of the means.
  6420. showextrema : bool, default = True
  6421. If true, will toggle rendering of the extrema.
  6422. showmedians : bool, default = False
  6423. If true, will toggle rendering of the medians.
  6424. Returns
  6425. -------
  6426. result : dict
  6427. A dictionary mapping each component of the violinplot to a
  6428. list of the corresponding collection instances created. The
  6429. dictionary has the following keys:
  6430. - ``bodies``: A list of the `~.collections.PolyCollection`
  6431. instances containing the filled area of each violin.
  6432. - ``cmeans``: A `~.collections.LineCollection` instance that marks
  6433. the mean values of each of the violin's distribution.
  6434. - ``cmins``: A `~.collections.LineCollection` instance that marks
  6435. the bottom of each violin's distribution.
  6436. - ``cmaxes``: A `~.collections.LineCollection` instance that marks
  6437. the top of each violin's distribution.
  6438. - ``cbars``: A `~.collections.LineCollection` instance that marks
  6439. the centers of each violin's distribution.
  6440. - ``cmedians``: A `~.collections.LineCollection` instance that
  6441. marks the median values of each of the violin's distribution.
  6442. - ``cquantiles``: A `~.collections.LineCollection` instance created
  6443. to identify the quantiles values of each of the violin's
  6444. distribution.
  6445. """
  6446. # Statistical quantities to be plotted on the violins
  6447. means = []
  6448. mins = []
  6449. maxes = []
  6450. medians = []
  6451. quantiles = np.asarray([])
  6452. # Collections to be returned
  6453. artists = {}
  6454. N = len(vpstats)
  6455. datashape_message = ("List of violinplot statistics and `{0}` "
  6456. "values must have the same length")
  6457. # Validate positions
  6458. if positions is None:
  6459. positions = range(1, N + 1)
  6460. elif len(positions) != N:
  6461. raise ValueError(datashape_message.format("positions"))
  6462. # Validate widths
  6463. if np.isscalar(widths):
  6464. widths = [widths] * N
  6465. elif len(widths) != N:
  6466. raise ValueError(datashape_message.format("widths"))
  6467. # Calculate ranges for statistics lines
  6468. pmins = -0.25 * np.array(widths) + positions
  6469. pmaxes = 0.25 * np.array(widths) + positions
  6470. # Check whether we are rendering vertically or horizontally
  6471. if vert:
  6472. fill = self.fill_betweenx
  6473. perp_lines = self.hlines
  6474. par_lines = self.vlines
  6475. else:
  6476. fill = self.fill_between
  6477. perp_lines = self.vlines
  6478. par_lines = self.hlines
  6479. if rcParams['_internal.classic_mode']:
  6480. fillcolor = 'y'
  6481. edgecolor = 'r'
  6482. else:
  6483. fillcolor = edgecolor = self._get_lines.get_next_color()
  6484. # Render violins
  6485. bodies = []
  6486. for stats, pos, width in zip(vpstats, positions, widths):
  6487. # The 0.5 factor reflects the fact that we plot from v-p to
  6488. # v+p
  6489. vals = np.array(stats['vals'])
  6490. vals = 0.5 * width * vals / vals.max()
  6491. bodies += [fill(stats['coords'],
  6492. -vals + pos,
  6493. vals + pos,
  6494. facecolor=fillcolor,
  6495. alpha=0.3)]
  6496. means.append(stats['mean'])
  6497. mins.append(stats['min'])
  6498. maxes.append(stats['max'])
  6499. medians.append(stats['median'])
  6500. q = stats.get('quantiles')
  6501. if q is not None:
  6502. # If exist key quantiles, assume it's a list of floats
  6503. quantiles = np.concatenate((quantiles, q))
  6504. artists['bodies'] = bodies
  6505. # Render means
  6506. if showmeans:
  6507. artists['cmeans'] = perp_lines(means, pmins, pmaxes,
  6508. colors=edgecolor)
  6509. # Render extrema
  6510. if showextrema:
  6511. artists['cmaxes'] = perp_lines(maxes, pmins, pmaxes,
  6512. colors=edgecolor)
  6513. artists['cmins'] = perp_lines(mins, pmins, pmaxes,
  6514. colors=edgecolor)
  6515. artists['cbars'] = par_lines(positions, mins, maxes,
  6516. colors=edgecolor)
  6517. # Render medians
  6518. if showmedians:
  6519. artists['cmedians'] = perp_lines(medians,
  6520. pmins,
  6521. pmaxes,
  6522. colors=edgecolor)
  6523. # Render quantile values
  6524. if quantiles.size > 0:
  6525. # Recalculate ranges for statistics lines for quantiles.
  6526. # ppmins are the left end of quantiles lines
  6527. ppmins = np.asarray([])
  6528. # pmaxes are the right end of quantiles lines
  6529. ppmaxs = np.asarray([])
  6530. for stats, cmin, cmax in zip(vpstats, pmins, pmaxes):
  6531. q = stats.get('quantiles')
  6532. if q is not None:
  6533. ppmins = np.concatenate((ppmins, [cmin] * np.size(q)))
  6534. ppmaxs = np.concatenate((ppmaxs, [cmax] * np.size(q)))
  6535. # Start rendering
  6536. artists['cquantiles'] = perp_lines(quantiles, ppmins, ppmaxs,
  6537. colors=edgecolor)
  6538. return artists
  6539. # Methods that are entirely implemented in other modules.
  6540. table = mtable.table
  6541. # args can by either Y or y1, y2, ... and all should be replaced
  6542. stackplot = _preprocess_data()(mstack.stackplot)
  6543. streamplot = _preprocess_data(
  6544. replace_names=["x", "y", "u", "v", "start_points"])(mstream.streamplot)
  6545. tricontour = mtri.tricontour
  6546. tricontourf = mtri.tricontourf
  6547. tripcolor = mtri.tripcolor
  6548. triplot = mtri.triplot