Interpretability of lung nodules segmentation
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main_code.ipynb 2.3MB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523285242852528526285272852828529285302853128532285332853428535285362853728538285392854028541285422854328544285452854628547285482854928550285512855228553285542855528556285572855828559285602856128562285632856428565285662856728568285692857028571285722857328574285752857628577285782857928580285812858228583285842858528586285872858828589285902859128592285932859428595285962859728598285992860028601286022860328604286052860628607286082860928610286112861228613286142861528616286172861828619286202862128622286232862428625286262862728628286292863028631286322863328634286352863628637286382863928640286412864228643286442864528646286472864828649286502865128652286532865428655286562865728658286592866028661286622866328664286652866628667286682866928670286712867228673286742867528676286772867828679286802868128682286832868428685286862868728688286892869028691286922869328694286952869628697286982869928700287012870228703287042870528706287072870828709287102871128712287132871428715287162871728718287192872028721287222872328724287252872628727287282872928730287312873228733287342873528736287372873828739287402874128742287432874428745287462874728748287492875028751287522875328754287552875628757287582875928760287612876228763287642876528766287672876828769287702877128772287732877428775287762877728778287792878028781287822878328784287852878628787287882878928790287912879228793287942879528796287972879828799288002880128802288032880428805288062880728808288092881028811288122881328814288152881628817288182881928820288212882228823288242882528826288272882828829288302883128832288332883428835288362883728838288392884028841288422884328844288452884628847288482884928850288512885228853288542885528856288572885828859288602886128862288632886428865288662886728868288692887028871288722887328874288752887628877288782887928880288812888228883288842888528886288872888828889288902889128892288932889428895288962889728898288992890028901289022890328904289052890628907289082890928910289112891228913289142891528916289172891828919289202892128922289232892428925289262892728928289292893028931289322893328934289352893628937289382893928940289412894228943289442894528946289472894828949289502895128952289532895428955289562895728958289592896028961289622896328964289652896628967289682896928970289712897228973289742897528976289772897828979289802898128982289832898428985289862898728988289892899028991289922899328994289952899628997289982899929000290012900229003290042900529006290072900829009290102901129012290132901429015290162901729018290192902029021290222902329024290252902629027290282902929030290312903229033290342903529036290372903829039290402904129042290432904429045290462904729048290492905029051290522905329054290552905629057290582905929060290612906229063290642906529066290672906829069290702907129072290732907429075290762907729078290792908029081290822908329084290852908629087290882908929090290912909229093290942909529096290972909829099291002910129102291032910429105291062910729108291092911029111291122911329114291152911629117291182911929120291212912229123291242912529126291272912829129291302913129132291332913429135291362913729138291392914029141291422914329144291452914629147291482914929150291512915229153291542915529156291572915829159291602916129162291632916429165291662916729168291692917029171291722917329174291752917629177291782917929180291812918229183291842918529186291872918829189291902919129192291932919429195291962919729198291992920029201292022920329204292052920629207292082920929210292112921229213292142921529216292172921829219292202922129222292232922429225292262922729228292292923029231292322923329234292352923629237292382923929240292412924229243292442924529246292472924829249292502925129252292532925429255292562925729258292592926029261292622926329264292652926629267292682926929270292712927229273292742927529276292772927829279292802928129282292832928429285292862928729288292892929029291292922929329294292952929629297292982929929300293012930229303293042930529306293072930829309293102931129312293132931429315293162931729318293192932029321293222932329324293252932629327293282932929330293312933229333293342933529336293372933829339293402934129342293432934429345293462934729348293492935029351293522935329354293552935629357293582935929360293612936229363293642936529366293672936829369293702937129372293732937429375293762937729378293792938029381293822938329384293852938629387293882938929390293912939229393293942939529396293972939829399294002940129402294032940429405294062940729408294092941029411294122941329414294152941629417294182941929420294212942229423294242942529426294272942829429294302943129432294332943429435294362943729438294392944029441294422944329444294452944629447294482944929450294512945229453294542945529456294572945829459294602946129462294632946429465294662946729468294692947029471294722947329474294752947629477294782947929480294812948229483294842948529486294872948829489294902949129492294932949429495294962949729498294992950029501295022950329504295052950629507295082950929510295112951229513295142951529516295172951829519295202952129522295232952429525295262952729528295292953029531295322953329534295352953629537295382953929540295412954229543295442954529546295472954829549295502955129552295532955429555295562955729558295592956029561295622956329564295652956629567295682956929570295712957229573295742957529576295772957829579295802958129582295832958429585295862958729588295892959029591295922959329594295952959629597295982959929600296012960229603296042960529606296072960829609296102961129612296132961429615296162961729618296192962029621296222962329624296252962629627296282962929630296312963229633296342963529636296372963829639296402964129642296432964429645296462964729648296492965029651296522965329654296552965629657296582965929660296612966229663296642966529666296672966829669296702967129672296732967429675296762967729678296792968029681296822968329684296852968629687296882968929690296912969229693296942969529696296972969829699297002970129702297032970429705297062970729708297092971029711297122971329714297152971629717297182971929720297212972229723297242972529726297272972829729297302973129732297332973429735297362973729738297392974029741297422974329744297452974629747297482974929750297512975229753297542975529756297572975829759297602976129762297632976429765297662976729768297692977029771297722977329774297752977629777297782977929780297812978229783297842978529786297872978829789297902979129792297932979429795297962979729798297992980029801298022980329804298052980629807298082980929810298112981229813298142981529816298172981829819298202982129822298232982429825298262982729828298292983029831298322983329834298352983629837298382983929840298412984229843298442984529846298472984829849298502985129852298532985429855298562985729858298592986029861298622986329864298652986629867298682986929870298712987229873298742987529876298772987829879298802988129882298832988429885298862988729888298892989029891298922989329894298952989629897298982989929900299012990229903299042990529906299072990829909299102991129912299132991429915299162991729918299192992029921299222992329924299252992629927299282992929930299312993229933299342993529936299372993829939299402994129942299432994429945299462994729948299492995029951299522995329954299552995629957299582995929960299612996229963299642996529966299672996829969299702997129972299732997429975299762997729978299792998029981299822998329984299852998629987299882998929990299912999229993299942999529996299972999829999300003000130002300033000430005300063000730008300093001030011300123001330014300153001630017300183001930020300213002230023300243002530026300273002830029300303003130032300333003430035300363003730038300393004030041300423004330044300453004630047300483004930050300513005230053300543005530056300573005830059300603006130062300633006430065300663006730068300693007030071300723007330074300753007630077300783007930080300813008230083300843008530086300873008830089300903009130092300933009430095300963009730098300993010030101301023010330104301053010630107301083010930110301113011230113301143011530116301173011830119301203012130122301233012430125301263012730128301293013030131301323013330134301353013630137301383013930140301413014230143301443014530146301473014830149301503015130152301533015430155301563015730158301593016030161301623016330164301653016630167301683016930170301713017230173301743017530176301773017830179301803018130182301833018430185301863018730188301893019030191301923019330194301953019630197301983019930200302013020230203302043020530206302073020830209302103021130212302133021430215302163021730218302193022030221302223022330224302253022630227302283022930230302313023230233302343023530236302373023830239302403024130242302433024430245302463024730248302493025030251302523025330254302553025630257302583025930260302613026230263302643026530266302673026830269302703027130272302733027430275302763027730278302793028030281302823028330284302853028630287302883028930290302913029230293302943029530296302973029830299303003030130302303033030430305303063030730308303093031030311303123031330314303153031630317303183031930320303213032230323303243032530326303273032830329303303033130332303333033430335303363033730338303393034030341303423034330344303453034630347303483034930350303513035230353303543035530356303573035830359303603036130362303633036430365303663036730368303693037030371303723037330374303753037630377303783037930380303813038230383303843038530386303873038830389303903039130392303933039430395303963039730398303993040030401304023040330404304053040630407304083040930410304113041230413304143041530416304173041830419304203042130422304233042430425304263042730428304293043030431304323043330434304353043630437304383043930440304413044230443304443044530446304473044830449304503045130452304533045430455304563045730458304593046030461304623046330464304653046630467304683046930470304713047230473304743047530476304773047830479304803048130482304833048430485304863048730488304893049030491304923049330494304953049630497304983049930500305013050230503305043050530506305073050830509305103051130512305133051430515305163051730518305193052030521305223052330524305253052630527305283052930530305313053230533305343053530536305373053830539305403054130542305433054430545305463054730548305493055030551305523055330554305553055630557305583055930560305613056230563305643056530566305673056830569305703057130572305733057430575305763057730578305793058030581305823058330584305853058630587305883058930590305913059230593305943059530596305973059830599306003060130602306033060430605306063060730608306093061030611306123061330614306153061630617306183061930620306213062230623306243062530626306273062830629306303063130632306333063430635306363063730638306393064030641306423064330644306453064630647306483064930650306513065230653306543065530656306573065830659306603066130662306633066430665306663066730668306693067030671306723067330674306753067630677306783067930680306813068230683306843068530686306873068830689306903069130692306933069430695306963069730698306993070030701307023070330704307053070630707307083070930710307113071230713307143071530716307173071830719307203072130722307233072430725307263072730728307293073030731307323073330734307353073630737307383073930740307413074230743307443074530746307473074830749307503075130752307533075430755307563075730758307593076030761307623076330764307653076630767307683076930770307713077230773307743077530776307773077830779307803078130782307833078430785307863078730788307893079030791307923079330794307953079630797307983079930800308013080230803308043080530806308073080830809308103081130812308133081430815308163081730818308193082030821308223082330824308253082630827308283082930830308313083230833308343083530836308373083830839308403084130842308433084430845308463084730848308493085030851308523085330854308553085630857308583085930860308613086230863308643086530866308673086830869308703087130872308733087430875308763087730878308793088030881308823088330884308853088630887308883088930890308913089230893308943089530896308973089830899309003090130902309033090430905309063090730908309093091030911309123091330914309153091630917309183091930920309213092230923309243092530926309273092830929309303093130932309333093430935309363093730938309393094030941309423094330944309453094630947309483094930950309513095230953309543095530956309573095830959309603096130962309633096430965309663096730968309693097030971309723097330974309753097630977309783097930980309813098230983309843098530986309873098830989309903099130992309933099430995309963099730998309993100031001310023100331004310053100631007310083100931010310113101231013310143101531016310173101831019310203102131022310233102431025310263102731028310293103031031310323103331034310353103631037310383103931040310413104231043310443104531046310473104831049310503105131052310533105431055310563105731058310593106031061310623106331064310653106631067310683106931070310713107231073310743107531076310773107831079310803108131082310833108431085310863108731088310893109031091310923109331094310953109631097310983109931100311013110231103311043110531106311073110831109311103111131112311133111431115311163111731118311193112031121311223112331124311253112631127311283112931130311313113231133311343113531136311373113831139311403114131142311433114431145311463114731148311493115031151311523115331154311553115631157311583115931160311613116231163311643116531166311673116831169311703117131172311733117431175311763117731178311793118031181311823118331184311853118631187311883118931190311913119231193311943119531196311973119831199312003120131202312033120431205312063120731208312093121031211312123121331214312153121631217312183121931220312213122231223312243122531226312273122831229312303123131232312333123431235312363123731238312393124031241312423124331244312453124631247312483124931250312513125231253312543125531256312573125831259312603126131262312633126431265312663126731268312693127031271312723127331274312753127631277312783127931280312813128231283312843128531286312873128831289312903129131292312933129431295312963129731298312993130031301313023130331304313053130631307313083130931310313113131231313313143131531316313173131831319313203132131322313233132431325313263132731328313293133031331313323133331334313353133631337313383133931340313413134231343313443134531346313473134831349313503135131352313533135431355313563135731358313593136031361313623136331364313653136631367313683136931370313713137231373313743137531376313773137831379313803138131382313833138431385313863138731388313893139031391313923139331394313953139631397313983139931400314013140231403314043140531406314073140831409314103141131412314133141431415314163141731418314193142031421314223142331424314253142631427314283142931430314313143231433314343143531436314373143831439314403144131442314433144431445314463144731448314493145031451314523145331454314553145631457314583145931460314613146231463314643146531466314673146831469314703147131472314733147431475314763147731478314793148031481314823148331484314853148631487314883148931490314913149231493314943149531496314973149831499315003150131502315033150431505315063150731508315093151031511315123151331514315153151631517315183151931520315213152231523315243152531526315273152831529315303153131532315333153431535315363153731538315393154031541315423154331544315453154631547315483154931550315513155231553315543155531556315573155831559315603156131562315633156431565315663156731568315693157031571315723157331574315753157631577315783157931580315813158231583315843158531586315873158831589315903159131592315933159431595315963159731598315993160031601316023160331604316053160631607316083160931610316113161231613316143161531616316173161831619316203162131622316233162431625316263162731628316293163031631316323163331634316353163631637316383163931640316413164231643316443164531646316473164831649316503165131652316533165431655316563165731658316593166031661316623166331664316653166631667316683166931670316713167231673316743167531676316773167831679316803168131682316833168431685316863168731688316893169031691316923169331694316953169631697316983169931700317013170231703317043170531706317073170831709317103171131712317133171431715317163171731718317193172031721317223172331724317253172631727317283172931730317313173231733317343173531736317373173831739317403174131742317433174431745317463174731748317493175031751317523175331754317553175631757317583175931760317613176231763317643176531766317673176831769317703177131772317733177431775317763177731778317793178031781317823178331784317853178631787317883178931790317913179231793317943179531796317973179831799318003180131802318033180431805318063180731808318093181031811318123181331814318153181631817318183181931820318213182231823318243182531826318273182831829318303183131832318333183431835318363183731838318393184031841318423184331844318453184631847318483184931850318513185231853318543185531856318573185831859318603186131862318633186431865318663186731868318693187031871318723187331874318753187631877318783187931880318813188231883318843188531886318873188831889318903189131892318933189431895318963189731898318993190031901319023190331904319053190631907319083190931910319113191231913319143191531916319173191831919319203192131922319233192431925319263192731928319293193031931319323193331934319353193631937319383193931940319413194231943319443194531946319473194831949319503195131952319533195431955319563195731958319593196031961319623196331964319653196631967319683196931970319713197231973319743197531976319773197831979319803198131982319833198431985319863198731988319893199031991319923199331994319953199631997319983199932000320013200232003320043200532006320073200832009320103201132012320133201432015320163201732018320193202032021320223202332024320253202632027320283202932030320313203232033320343203532036320373203832039320403204132042320433204432045320463204732048320493205032051320523205332054320553205632057320583205932060320613206232063320643206532066320673206832069320703207132072320733207432075320763207732078320793208032081320823208332084320853208632087320883208932090320913209232093320943209532096320973209832099321003210132102321033210432105321063210732108321093211032111321123211332114321153211632117321183211932120321213212232123321243212532126321273212832129321303213132132321333213432135321363213732138321393214032141321423214332144321453214632147321483214932150321513215232153321543215532156321573215832159321603216132162321633216432165321663216732168321693217032171321723217332174321753217632177321783217932180321813218232183321843218532186321873218832189321903219132192321933219432195321963219732198321993220032201322023220332204322053220632207322083220932210322113221232213322143221532216322173221832219322203222132222322233222432225322263222732228322293223032231322323223332234322353223632237322383223932240322413224232243322443224532246322473224832249322503225132252322533225432255322563225732258322593226032261322623226332264322653226632267322683226932270322713227232273322743227532276322773227832279322803228132282322833228432285322863228732288322893229032291322923229332294322953229632297322983229932300323013230232303323043230532306323073230832309323103231132312323133231432315323163231732318323193232032321323223232332324323253232632327323283232932330323313233232333323343233532336323373233832339323403234132342323433234432345323463234732348323493235032351323523235332354323553235632357323583235932360323613236232363323643236532366323673236832369323703237132372323733237432375323763237732378323793238032381323823238332384323853238632387323883238932390323913239232393323943239532396323973239832399324003240132402324033240432405324063240732408324093241032411324123241332414324153241632417324183241932420324213242232423324243242532426324273242832429324303243132432324333243432435324363243732438324393244032441324423244332444324453244632447324483244932450324513245232453324543245532456324573245832459324603246132462324633246432465324663246732468324693247032471324723247332474324753247632477324783247932480324813248232483324843248532486324873248832489324903249132492324933249432495324963249732498324993250032501325023250332504325053250632507325083250932510325113251232513325143251532516325173251832519325203252132522325233252432525325263252732528325293253032531325323253332534325353253632537325383253932540325413254232543325443254532546325473254832549325503255132552325533255432555325563255732558325593256032561325623256332564325653256632567325683256932570325713257232573325743257532576325773257832579325803258132582325833258432585325863258732588325893259032591325923259332594325953259632597325983259932600326013260232603326043260532606326073260832609326103261132612326133261432615326163261732618326193262032621326223262332624326253262632627326283262932630326313263232633326343263532636326373263832639326403264132642326433264432645326463264732648326493265032651326523265332654326553265632657326583265932660326613266232663326643266532666326673266832669326703267132672326733267432675326763267732678326793268032681326823268332684326853268632687326883268932690326913269232693326943269532696326973269832699327003270132702327033270432705327063270732708327093271032711327123271332714327153271632717327183271932720327213272232723327243272532726327273272832729327303273132732327333273432735327363273732738327393274032741327423274332744327453274632747327483274932750327513275232753327543275532756327573275832759327603276132762327633276432765327663276732768327693277032771327723277332774327753277632777327783277932780327813278232783327843278532786327873278832789327903279132792327933279432795327963279732798327993280032801328023280332804328053280632807328083280932810328113281232813328143281532816328173281832819328203282132822328233282432825328263282732828328293283032831328323283332834328353283632837328383283932840328413284232843328443284532846328473284832849328503285132852328533285432855328563285732858328593286032861328623286332864328653286632867328683286932870328713287232873328743287532876328773287832879328803288132882328833288432885328863288732888328893289032891328923289332894328953289632897328983289932900329013290232903329043290532906329073290832909329103291132912329133291432915329163291732918329193292032921329223292332924329253292632927329283292932930329313293232933329343293532936329373293832939329403294132942329433294432945329463294732948329493295032951329523295332954329553295632957329583295932960329613296232963329643296532966329673296832969329703297132972329733297432975329763297732978329793298032981329823298332984329853298632987329883298932990329913299232993329943299532996329973299832999330003300133002330033300433005330063300733008330093301033011330123301333014330153301633017330183301933020330213302233023330243302533026330273302833029330303303133032330333303433035330363303733038330393304033041330423304333044330453304633047330483304933050330513305233053330543305533056330573305833059330603306133062330633306433065330663306733068330693307033071330723307333074330753307633077330783307933080330813308233083330843308533086330873308833089330903309133092330933309433095330963309733098330993310033101331023310333104331053310633107331083310933110331113311233113331143311533116331173311833119331203312133122331233312433125331263312733128331293313033131331323313333134331353313633137331383313933140331413314233143331443314533146331473314833149331503315133152331533315433155331563315733158331593316033161331623316333164331653316633167331683316933170331713317233173331743317533176331773317833179331803318133182331833318433185331863318733188331893319033191331923319333194331953319633197331983319933200332013320233203332043320533206332073320833209332103321133212332133321433215332163321733218332193322033221332223322333224332253322633227332283322933230332313323233233332343323533236332373323833239332403324133242332433324433245332463324733248332493325033251332523325333254332553325633257332583325933260332613326233263332643326533266332673326833269332703327133272332733327433275332763327733278332793328033281332823328333284332853328633287332883328933290332913329233293332943329533296332973329833299333003330133302333033330433305333063330733308333093331033311333123331333314333153331633317333183331933320333213332233323333243332533326333273332833329333303333133332333333333433335333363333733338333393334033341333423334333344333453334633347333483334933350333513335233353333543335533356333573335833359333603336133362333633336433365333663336733368333693337033371333723337333374333753337633377333783337933380333813338233383333843338533386333873338833389333903339133392333933339433395333963339733398333993340033401334023340333404334053340633407334083340933410334113341233413334143341533416334173341833419334203342133422334233342433425334263342733428334293343033431334323343333434334353343633437334383343933440334413344233443334443344533446334473344833449334503345133452334533345433455334563345733458334593346033461334623346333464334653346633467334683346933470334713347233473334743347533476334773347833479334803348133482334833348433485334863348733488334893349033491334923349333494334953349633497334983349933500335013350233503335043350533506335073350833509335103351133512335133351433515335163351733518335193352033521335223352333524335253352633527335283352933530335313353233533335343353533536335373353833539335403354133542335433354433545335463354733548335493355033551335523355333554335553355633557335583355933560335613356233563335643356533566335673356833569335703357133572335733357433575335763357733578335793358033581335823358333584335853358633587335883358933590335913359233593335943359533596335973359833599336003360133602336033360433605336063360733608336093361033611336123361333614336153361633617336183361933620336213362233623336243362533626336273362833629336303363133632336333363433635336363363733638336393364033641336423364333644336453364633647336483364933650336513365233653336543365533656336573365833659336603366133662336633366433665336663366733668336693367033671336723367333674336753367633677336783367933680336813368233683336843368533686336873368833689336903369133692336933369433695336963369733698336993370033701337023370333704337053370633707337083370933710337113371233713337143371533716337173371833719337203372133722337233372433725337263372733728337293373033731337323373333734337353373633737337383373933740337413374233743337443374533746337473374833749337503375133752337533375433755337563375733758337593376033761337623376333764337653376633767337683376933770337713377233773337743377533776337773377833779337803378133782337833378433785337863378733788337893379033791337923379333794337953379633797337983379933800338013380233803338043380533806338073380833809338103381133812338133381433815338163381733818338193382033821338223382333824338253382633827338283382933830338313383233833338343383533836338373383833839338403384133842338433384433845338463384733848338493385033851338523385333854338553385633857338583385933860338613386233863338643386533866338673386833869338703387133872338733387433875338763387733878338793388033881338823388333884338853388633887338883388933890338913389233893338943389533896338973389833899339003390133902339033390433905339063390733908339093391033911339123391333914339153391633917339183391933920339213392233923339243392533926339273392833929339303393133932339333393433935339363393733938339393394033941339423394333944339453394633947339483394933950339513395233953339543395533956339573395833959339603396133962339633396433965339663396733968339693397033971339723397333974339753397633977339783397933980339813398233983339843398533986339873398833989339903399133992339933399433995339963399733998339993400034001340023400334004340053400634007340083400934010340113401234013340143401534016340173401834019340203402134022340233402434025340263402734028340293403034031340323403334034340353403634037340383403934040340413404234043340443404534046340473404834049340503405134052340533405434055340563405734058340593406034061340623406334064340653406634067340683406934070340713407234073340743407534076340773407834079340803408134082340833408434085340863408734088340893409034091340923409334094340953409634097340983409934100341013410234103341043410534106341073410834109341103411134112341133411434115341163411734118341193412034121341223412334124341253412634127341283412934130341313413234133341343413534136341373413834139341403414134142341433414434145341463414734148341493415034151341523415334154341553415634157341583415934160341613416234163341643416534166341673416834169341703417134172341733417434175341763417734178341793418034181341823418334184341853418634187341883418934190341913419234193341943419534196341973419834199342003420134202342033420434205342063420734208342093421034211342123421334214342153421634217342183421934220342213422234223342243422534226342273422834229342303423134232342333423434235
  1. {
  2. "cells": [
  3. {
  4. "cell_type": "code",
  5. "execution_count": 1,
  6. "metadata": {},
  7. "outputs": [],
  8. "source": [
  9. "%matplotlib inline\n",
  10. "# %matplotlib notebook\n",
  11. "%load_ext autoreload\n",
  12. "%autoreload 2\n",
  13. "\n",
  14. "\n",
  15. "import os,sys\n",
  16. "import pandas as pd\n",
  17. "import matplotlib.pyplot as plt\n",
  18. "import numpy as np\n",
  19. "import helper\n",
  20. "import simulation\n",
  21. "\n",
  22. "# print(sys.version_info)\n",
  23. "\n",
  24. "# # Generate some random images\n",
  25. "# input_images, target_masks = simulation.generate_random_data(192, 192, count=3)\n",
  26. "\n",
  27. "# # for x in [input_images, target_masks]:\n",
  28. "# # print(x.shape)\n",
  29. "# # print(x.min(), x.max())\n",
  30. "# # print(len(input_images))\n",
  31. "# # print(input_images[0].shape)\n",
  32. "# # print(target_masks[0].shape)\n",
  33. "\n",
  34. "\n",
  35. "# # Change channel-order and make 3 channels for matplot\n",
  36. "# input_images_rgb = [x.astype(np.uint8) for x in input_images]\n",
  37. "\n",
  38. "# # Map each channel (i.e. class) to each color\n",
  39. "# target_masks_rgb = [helper.masks_to_colorimg(x) for x in target_masks]\n",
  40. "# # print(target_masks[0][0])\n",
  41. "# # print(target_masks_rgb[0][0][0])\n",
  42. "# # Left: Input image, Right: Target mask (Ground-truth)\n",
  43. "# # print(input_images_rgb[0].shape)\n",
  44. "# # print(target_masks_rgb[0].shape)\n",
  45. "# helper.plot_side_by_side([input_images_rgb, target_masks_rgb])\n",
  46. "# # helper.plot_side_by_side([input_images, target_masks])\n"
  47. ]
  48. },
  49. {
  50. "cell_type": "code",
  51. "execution_count": null,
  52. "metadata": {},
  53. "outputs": [],
  54. "source": []
  55. },
  56. {
  57. "cell_type": "code",
  58. "execution_count": 2,
  59. "metadata": {},
  60. "outputs": [],
  61. "source": [
  62. "# the first working version which one slice was copied in 3 channels 3 times and was working without bug\n",
  63. "\n",
  64. "# from torch.utils.data import Dataset, DataLoader\n",
  65. "# import torch\n",
  66. "# print(torch.cuda.is_available())\n",
  67. "\n",
  68. "# from torchvision import transforms\n",
  69. "# from torchvision import datasets\n",
  70. "# import natsort\n",
  71. "# from PIL import *\n",
  72. "# import albumentations as A\n",
  73. "# # cwd = os.getcwd()\n",
  74. "# # print(cwd)\n",
  75. "\n",
  76. "# def showIm(img) -> None:\n",
  77. "# \"\"\"\n",
  78. "# View multiple images stored in files, stacking vertically\n",
  79. "\n",
  80. "# Arguments:\n",
  81. "# filename: str - path to filename containing image\n",
  82. "# \"\"\"\n",
  83. " \n",
  84. "# # <something gets done here>\n",
  85. "# plt.figure()\n",
  86. "# plt.imshow(img)\n",
  87. "\n",
  88. "# def showAll(picList):\n",
  89. "# for im in picList:\n",
  90. "# plt.figure()\n",
  91. "# plt.imshow(im)\n",
  92. " \n",
  93. "# imgList = []\n",
  94. "\n",
  95. "# class SimDataset(Dataset):\n",
  96. "# def __init__(self, main_dir, transform=None):\n",
  97. "# # self.input_images, self.target_masks = simulation.generate_random_data(192, 192, count=count) \n",
  98. "# self.main_dir = main_dir\n",
  99. "# self.transform = transform\n",
  100. "# self.input_images = os.listdir(main_dir + '/image/')\n",
  101. "# self.target_masks = os.listdir(main_dir + '/mask')\n",
  102. "# self.input_images = natsort.natsorted(self.input_images)\n",
  103. "# self.target_masks = natsort.natsorted(self.target_masks)\n",
  104. "\n",
  105. "# def __len__(self):\n",
  106. "# return len(self.input_images)\n",
  107. " \n",
  108. "\n",
  109. "# def __getitem__(self, idx): \n",
  110. "# image = self.input_images[idx]\n",
  111. "# mask = self.target_masks[idx]\n",
  112. " \n",
  113. "# img_loc = os.path.join(self.main_dir, 'image', image)\n",
  114. "# mask_loc = os.path.join(self.main_dir, 'mask', mask)\n",
  115. "\n",
  116. "# # image = np.load(img_loc).type(torch.FloatTensor)\n",
  117. "# # mask = np.load(mask_loc).type(torch.FloatTensor)\n",
  118. "# image = torch.from_numpy(np.load(img_loc)).type(torch.FloatTensor)\n",
  119. "# mask = torch.from_numpy(np.load(mask_loc)).type(torch.FloatTensor)\n",
  120. " \n",
  121. "# # mask = 1 - mask\n",
  122. "# imgList.append(image)\n",
  123. "# imgList.append(mask)\n",
  124. " \n",
  125. "# image = np.repeat(image[np.newaxis, :,:], 3, axis=0)\n",
  126. "# mask = np.repeat(mask[np.newaxis, :, :], 1, axis=0)\n",
  127. "# # image = np.transpose(image, (1, 2, 0))\n",
  128. "# # mask = np.transpose(mask, (1, 2, 0))\n",
  129. " \n",
  130. " \n",
  131. "# if self.transform:\n",
  132. "# transformed = self.transform(image=image, mask=mask)\n",
  133. " \n",
  134. "# return [image, mask]\n",
  135. "\n",
  136. "# # n = 1\n",
  137. "# # train_dataset_path = './data/train1'\n",
  138. "# # val_dataset_path = './data/val1'\n",
  139. "# # n = 32\n",
  140. "# train_dataset_path = './data/train'\n",
  141. "# val_dataset_path = './data/val'\n",
  142. "# # n = all\n",
  143. "# # train_dataset_path = './data/trainold'\n",
  144. "# # val_dataset_path = './data/valold'\n",
  145. "\n",
  146. "\n",
  147. "# train_set = SimDataset(\n",
  148. "# main_dir=train_dataset_path, \n",
  149. "# transform=None\n",
  150. "# )\n",
  151. "# val_set = SimDataset(\n",
  152. "# main_dir=val_dataset_path, \n",
  153. "# transform=None\n",
  154. "# )\n",
  155. "\n",
  156. "# image_datasets = {\n",
  157. "# 'train': train_set, 'val': val_set\n",
  158. "# }\n",
  159. "\n",
  160. "# batch_size = 4\n",
  161. "# num_workers = 25\n",
  162. "\n",
  163. "# dataloaders = {\n",
  164. "# 'train': DataLoader(train_set, batch_size=batch_size, shuffle=True, num_workers=num_workers),\n",
  165. "# 'val': DataLoader(val_set, batch_size=batch_size, shuffle=True, num_workers=num_workers)\n",
  166. "# }\n",
  167. "\n",
  168. "# dataset_sizes = {\n",
  169. "# x: len(image_datasets[x]) for x in image_datasets.keys()\n",
  170. "# }\n",
  171. "\n",
  172. "# inputs, masks = next(iter(dataloaders['train']))\n",
  173. "# num = 0\n",
  174. "# print(inputs.shape)\n",
  175. "# print(masks.shape)\n",
  176. "# img = inputs[0][0]\n",
  177. "# mask = masks[0][0]\n",
  178. "# img = inputs[num][0]\n",
  179. "\n",
  180. "# imgList.append(img)\n",
  181. "# imgList.append(mask)\n",
  182. "\n",
  183. "# print(img.shape)\n",
  184. "# showAll(imgList)"
  185. ]
  186. },
  187. {
  188. "cell_type": "code",
  189. "execution_count": 3,
  190. "metadata": {},
  191. "outputs": [
  192. {
  193. "name": "stdout",
  194. "output_type": "stream",
  195. "text": [
  196. "True\n",
  197. "torch.Size([8, 3, 512, 512])\n",
  198. "torch.Size([8, 1, 512, 512])\n",
  199. "torch.Size([512, 512])\n"
  200. ]
  201. },
  202. {
  203. "data": {
  204. "image/png": "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\n",
  205. "text/plain": [
  206. "<Figure size 432x288 with 1 Axes>"
  207. ]
  208. },
  209. "metadata": {
  210. "needs_background": "light"
  211. },
  212. "output_type": "display_data"
  213. },
  214. {
  215. "data": {
  216. "image/png": "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\n",
  217. "text/plain": [
  218. "<Figure size 432x288 with 1 Axes>"
  219. ]
  220. },
  221. "metadata": {
  222. "needs_background": "light"
  223. },
  224. "output_type": "display_data"
  225. }
  226. ],
  227. "source": [
  228. "# 3 different slices in each channel\n",
  229. "\n",
  230. "from torch.utils.data import Dataset, DataLoader\n",
  231. "import torch\n",
  232. "print(torch.cuda.is_available())\n",
  233. "\n",
  234. "from torchvision import transforms\n",
  235. "from torchvision import datasets\n",
  236. "import natsort\n",
  237. "from PIL import *\n",
  238. "import albumentations as A\n",
  239. "# cwd = os.getcwd()\n",
  240. "# print(cwd)\n",
  241. "\n",
  242. "def showIm(img) -> None:\n",
  243. " \"\"\"\n",
  244. " View multiple images stored in files, stacking vertically\n",
  245. "\n",
  246. " Arguments:\n",
  247. " filename: str - path to filename containing image\n",
  248. " \"\"\"\n",
  249. " \n",
  250. " # <something gets done here>\n",
  251. " plt.figure()\n",
  252. " plt.imshow(img)\n",
  253. "\n",
  254. "def showAll(picList):\n",
  255. " for im in picList:\n",
  256. " plt.figure()\n",
  257. " plt.imshow(im)\n",
  258. " \n",
  259. "imgList = []\n",
  260. "\n",
  261. "class SimDataset(Dataset):\n",
  262. " def __init__(self, main_dir, transform=None):\n",
  263. "# self.input_images, self.target_masks = simulation.generate_random_data(192, 192, count=count) \n",
  264. " self.main_dir = main_dir\n",
  265. " self.transform = transform\n",
  266. " self.input_images = os.listdir(main_dir + '/image/')\n",
  267. " self.target_masks = os.listdir(main_dir + '/mask')\n",
  268. " self.input_images = natsort.natsorted(self.input_images)\n",
  269. " self.target_masks = natsort.natsorted(self.target_masks)\n",
  270. "\n",
  271. " def __len__(self):\n",
  272. " return len(self.input_images)\n",
  273. " \n",
  274. " def _get_prev_next(self, idx, image_list_set, mask_list_set):\n",
  275. " main_slice = self.input_images[idx]\n",
  276. " \n",
  277. " slice_num = int(main_slice[16:19])\n",
  278. " prev_num = slice_num - 1\n",
  279. " next_num = slice_num + 1\n",
  280. " \n",
  281. " prev_num = \"%03d\" % prev_num\n",
  282. " next_num = \"%03d\" % next_num\n",
  283. " \n",
  284. " \n",
  285. " prev_slice = prev_num.join([main_slice[0:15], main_slice[19:]])\n",
  286. " next_slice = next_num.join([main_slice[0:15], main_slice[19:]])\n",
  287. " \n",
  288. " if not (prev_slice in image_list_set):\n",
  289. " prev_slice = main_slice\n",
  290. " if not (next_slice in image_list_set):\n",
  291. " next_slice = main_slice\n",
  292. " \n",
  293. "# print(type(self.input_images))\n",
  294. "# print(str(type(main_slice)) + ' ' + main_slice + ' ' + str(slice_num) + ' ' + str(prev_num) + ' ' + str(next_num) + ' ' + prev_slice + ' ' + next_slice)\n",
  295. "# print(main_slice)\n",
  296. "# print()\n",
  297. " return prev_slice, next_slice\n",
  298. " \n",
  299. " def __getitem__(self, idx): \n",
  300. " image = self.input_images[idx]\n",
  301. " mask = self.target_masks[idx]\n",
  302. " \n",
  303. " \n",
  304. " image_list_set = set(self.input_images)\n",
  305. " mask_list_set = set(self.target_masks)\n",
  306. " \n",
  307. " prev_slice, next_slice = self._get_prev_next(idx, image_list_set, mask_list_set)\n",
  308. " \n",
  309. " prev_loc = os.path.join(self.main_dir, 'image', prev_slice)\n",
  310. " next_loc = os.path.join(self.main_dir, 'image', next_slice)\n",
  311. " img_loc = os.path.join(self.main_dir, 'image', image)\n",
  312. " mask_loc = os.path.join(self.main_dir, 'mask', mask)\n",
  313. "\n",
  314. "# image = np.load(img_loc).type(torch.FloatTensor)\n",
  315. "# mask = np.load(mask_loc).type(torch.FloatTensor)\n",
  316. " mid_slice = torch.from_numpy(np.load(img_loc)).type(torch.FloatTensor)\n",
  317. " prev_slice = torch.from_numpy(np.load(prev_loc)).type(torch.FloatTensor)\n",
  318. " next_slice = torch.from_numpy(np.load(next_loc)).type(torch.FloatTensor)\n",
  319. " mask = torch.from_numpy(np.load(mask_loc)).type(torch.FloatTensor)\n",
  320. " \n",
  321. " image_3d = torch.stack([prev_slice, mid_slice, next_slice], dim=0)\n",
  322. " \n",
  323. " # mask = 1 - mask\n",
  324. " \n",
  325. "# print(image_3d.shape)\n",
  326. "# self._get_prev_next(idx, image_list_set, mask_list_set)\n",
  327. " \n",
  328. " image = np.repeat(image_3d[np.newaxis, :,:], 1, axis=0)\n",
  329. " mask = np.repeat(mask[np.newaxis, :, :], 1, axis=0)\n",
  330. "# image = np.transpose(image, (1, 2, 0))\n",
  331. "# mask = np.transpose(mask, (1, 2, 0))\n",
  332. " \n",
  333. " \n",
  334. " if self.transform:\n",
  335. " transformed = self.transform(image=image, mask=mask)\n",
  336. " \n",
  337. " return [image_3d, mask]\n",
  338. "\n",
  339. "# n = 1\n",
  340. "# train_dataset_path = './data/train1'\n",
  341. "# val_dataset_path = './data/val1'\n",
  342. "# n = 32\n",
  343. "train_dataset_path = './data/train'\n",
  344. "val_dataset_path = './data/val'\n",
  345. "# n = all\n",
  346. "# train_dataset_path = './data/trainold'\n",
  347. "# val_dataset_path = './data/valold'\n",
  348. "\n",
  349. "\n",
  350. "train_set = SimDataset(\n",
  351. " main_dir=train_dataset_path, \n",
  352. " transform=None\n",
  353. ")\n",
  354. "val_set = SimDataset(\n",
  355. " main_dir=val_dataset_path, \n",
  356. " transform=None\n",
  357. ")\n",
  358. "\n",
  359. "image_datasets = {\n",
  360. " 'train': train_set, 'val': val_set\n",
  361. "}\n",
  362. "\n",
  363. "batch_size = 8\n",
  364. "num_workers = 25\n",
  365. "\n",
  366. "dataloaders = {\n",
  367. " 'train': DataLoader(train_set, batch_size=batch_size, shuffle=True, num_workers=num_workers),\n",
  368. " 'val': DataLoader(val_set, batch_size=batch_size, shuffle=True, num_workers=num_workers)\n",
  369. "}\n",
  370. "\n",
  371. "dataset_sizes = {\n",
  372. " x: len(image_datasets[x]) for x in image_datasets.keys()\n",
  373. "}\n",
  374. "\n",
  375. "inputs, masks = next(iter(dataloaders['train']))\n",
  376. "num = 0\n",
  377. "print(inputs.shape)\n",
  378. "print(masks.shape)\n",
  379. "img = inputs[0][0]\n",
  380. "mask = masks[0][0]\n",
  381. "img = inputs[num][0]\n",
  382. "\n",
  383. "imgList.append(img)\n",
  384. "imgList.append(mask)\n",
  385. "\n",
  386. "print(img.shape)\n",
  387. "showAll(imgList)"
  388. ]
  389. },
  390. {
  391. "cell_type": "code",
  392. "execution_count": 4,
  393. "metadata": {},
  394. "outputs": [],
  395. "source": [
  396. "# import torchvision.utils\n",
  397. "\n",
  398. "# def reverse_transform(inp):\n",
  399. "# inp = inp.numpy().transpose((1, 2, 0))\n",
  400. "# inp = np.clip(inp, 0, 1)\n",
  401. "# inp = (inp * 255).astype(np.uint8)\n",
  402. " \n",
  403. "# return inp\n",
  404. "\n",
  405. "# print(target_masks_rgb[0].shape)\n",
  406. "# print(reverse_transform(target_masks_rgb[0]).shape)\n"
  407. ]
  408. },
  409. {
  410. "cell_type": "code",
  411. "execution_count": 5,
  412. "metadata": {},
  413. "outputs": [],
  414. "source": [
  415. "# inputs, masks = next(iter(dataloaders['train']))\n",
  416. "\n",
  417. "# print(inputs.shape, masks.shape)\n",
  418. "# for x in [inputs.numpy(), masks.numpy()]:\n",
  419. "# print(x.min(), x.max(), x.mean(), x.std())\n",
  420. "\n",
  421. "# plt.imshow(reverse_transform(inputs[3]))"
  422. ]
  423. },
  424. {
  425. "cell_type": "markdown",
  426. "metadata": {},
  427. "source": [
  428. "##### import torchvision.utils\n",
  429. "\n",
  430. "def reverse_transform(inp):\n",
  431. " inp = inp.numpy().transpose((1, 2, 0))\n",
  432. " inp = np.clip(inp, 0, 1)\n",
  433. " inp = (inp * 255).astype(np.uint8)\n",
  434. " \n",
  435. " return inp\n",
  436. "\n",
  437. "# Get a batch of training data\n",
  438. "inputs, masks = next(iter(dataloaders['train']))\n",
  439. "\n",
  440. "print(inputs.shape, masks.shape)\n",
  441. "for x in [inputs.numpy(), masks.numpy()]:\n",
  442. " print(x.min(), x.max(), x.mean(), x.std())\n",
  443. "\n",
  444. "plt.imshow(reverse_transform(inputs[3]))"
  445. ]
  446. },
  447. {
  448. "cell_type": "code",
  449. "execution_count": 6,
  450. "metadata": {},
  451. "outputs": [],
  452. "source": [
  453. "from torchsummary import summary\n",
  454. "import torch\n",
  455. "import torch.nn as nn\n",
  456. "import pytorch_unet\n",
  457. "\n",
  458. "# device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n",
  459. "\n",
  460. "n_out_class = 1\n",
  461. "\n",
  462. "# model = pytorch_unet.UNet(n_out_class)\n",
  463. "# model = torch.hub.load('mateuszbuda/brain-segmentation-pytorch', 'unet',\n",
  464. "# in_channels=1, out_channels=1, init_features=32, pretrained=False)\n",
  465. "\n",
  466. "# model = model.to(device)\n",
  467. "\n",
  468. "# print(next(model.parameters()).is_cuda)\n",
  469. "\n",
  470. "# summary(model, input_size=(1, 512, 512))"
  471. ]
  472. },
  473. {
  474. "cell_type": "code",
  475. "execution_count": 7,
  476. "metadata": {},
  477. "outputs": [],
  478. "source": [
  479. "\n",
  480. "# import torch\n",
  481. "# import torch.nn as nn\n",
  482. "# import torch.nn.functional as F\n",
  483. "# import torchvision\n",
  484. "\n",
  485. "# class DoubleConv(nn.Module):\n",
  486. "# \"\"\"(convolution => [BN] => ReLU) * 2\"\"\"\n",
  487. "\n",
  488. "# def __init__(self, in_channels, out_channels, mid_channels=None):\n",
  489. "# super().__init__()\n",
  490. "# if not mid_channels:\n",
  491. "# mid_channels = out_channels\n",
  492. "# self.double_conv = nn.Sequential(\n",
  493. "# nn.Conv2d(in_channels, mid_channels, kernel_size=3, padding=1),\n",
  494. "# nn.BatchNorm2d(mid_channels),\n",
  495. "# nn.ReLU(inplace=True),\n",
  496. "# nn.Conv2d(mid_channels, out_channels, kernel_size=3, padding=1),\n",
  497. "# nn.BatchNorm2d(out_channels),\n",
  498. "# nn.ReLU(inplace=True)\n",
  499. "# )\n",
  500. "\n",
  501. "# def forward(self, x):\n",
  502. "# return self.double_conv(x)\n",
  503. "\n",
  504. "\n",
  505. "# class Down(nn.Module):\n",
  506. "# \"\"\"Downscaling with maxpool then double conv\"\"\"\n",
  507. "\n",
  508. "# def __init__(self, in_channels, out_channels):\n",
  509. "# super().__init__()\n",
  510. "# self.maxpool_conv = nn.Sequential(\n",
  511. "# nn.MaxPool2d(2),\n",
  512. "# DoubleConv(in_channels, out_channels)\n",
  513. "# )\n",
  514. "\n",
  515. "# def forward(self, x):\n",
  516. "# return self.maxpool_conv(x)\n",
  517. "\n",
  518. "\n",
  519. "# class Up(nn.Module):\n",
  520. "# \"\"\"Upscaling then double conv\"\"\"\n",
  521. "\n",
  522. "# def __init__(self, in_channels, out_channels, bilinear=True):\n",
  523. "# super().__init__()\n",
  524. "\n",
  525. "# # if bilinear, use the normal convolutions to reduce the number of channels\n",
  526. "# if bilinear:\n",
  527. "# self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)\n",
  528. "# self.conv = DoubleConv(in_channels, out_channels, in_channels // 2)\n",
  529. "# else:\n",
  530. "# self.up = nn.ConvTranspose2d(in_channels , in_channels // 2, kernel_size=2, stride=2)\n",
  531. "# self.conv = DoubleConv(in_channels, out_channels)\n",
  532. "\n",
  533. "\n",
  534. "# def forward(self, x1, x2):\n",
  535. "# x1 = self.up(x1)\n",
  536. "# # input is CHW\n",
  537. "# diffY = x2.size()[2] - x1.size()[2]\n",
  538. "# diffX = x2.size()[3] - x1.size()[3]\n",
  539. "\n",
  540. "# x1 = F.pad(x1, [diffX // 2, diffX - diffX // 2,\n",
  541. "# diffY // 2, diffY - diffY // 2])\n",
  542. "# # if you have padding issues, see\n",
  543. "# # https://github.com/HaiyongJiang/U-Net-Pytorch-Unstructured-Buggy/commit/0e854509c2cea854e247a9c615f175f76fbb2e3a\n",
  544. "# # https://github.com/xiaopeng-liao/Pytorch-UNet/commit/8ebac70e633bac59fc22bb5195e513d5832fb3bd\n",
  545. "# x = torch.cat([x2, x1], dim=1)\n",
  546. "# return self.conv(x)\n",
  547. "\n",
  548. "# class OutConv(nn.Module):\n",
  549. "# def __init__(self, in_channels, out_channels):\n",
  550. "# super(OutConv, self).__init__()\n",
  551. "# self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=1)\n",
  552. "\n",
  553. "# def forward(self, x):\n",
  554. "# return self.conv(x)\n"
  555. ]
  556. },
  557. {
  558. "cell_type": "code",
  559. "execution_count": 8,
  560. "metadata": {},
  561. "outputs": [],
  562. "source": [
  563. "# \"\"\" Full assembly of the parts to form the complete network \"\"\"\n",
  564. "\n",
  565. "# import torch.nn.functional as F\n",
  566. "\n",
  567. "# # from .unet_parts import *\n",
  568. "\n",
  569. "\n",
  570. "# class NewUnet(nn.Module):\n",
  571. "# def __init__(self, n_channels, n_classes, bilinear=True):\n",
  572. "# super(NewUnet, self).__init__()\n",
  573. "# self.n_channels = n_channels\n",
  574. "# self.n_classes = n_classes\n",
  575. "# self.bilinear = bilinear\n",
  576. "\n",
  577. "# self.inc = DoubleConv(n_channels, 64)\n",
  578. "# self.down1 = Down(64, 128)\n",
  579. "# self.down2 = Down(128, 256)\n",
  580. "# self.down3 = Down(256, 512)\n",
  581. "# factor = 2 if bilinear else 1\n",
  582. "# self.down4 = Down(512, 1024 // factor)\n",
  583. "# self.up1 = Up(1024, 512 // factor, bilinear)\n",
  584. "# self.up2 = Up(512, 256 // factor, bilinear)\n",
  585. "# self.up3 = Up(256, 128 // factor, bilinear)\n",
  586. "# self.up4 = Up(128, 64, bilinear)\n",
  587. "# self.outc = OutConv(64, n_classes)\n",
  588. "\n",
  589. "# def forward(self, x):\n",
  590. "# x1 = self.inc(x)\n",
  591. "# x2 = self.down1(x1)\n",
  592. "# x3 = self.down2(x2)\n",
  593. "# x4 = self.down3(x3)\n",
  594. "# x5 = self.down4(x4)\n",
  595. "# x = self.up1(x5, x4)\n",
  596. "# x = self.up2(x, x3)\n",
  597. "# x = self.up3(x, x2)\n",
  598. "# x = self.up4(x, x1)\n",
  599. "# logits = self.outc(x)\n",
  600. "# return logits"
  601. ]
  602. },
  603. {
  604. "cell_type": "code",
  605. "execution_count": 9,
  606. "metadata": {},
  607. "outputs": [],
  608. "source": [
  609. "import torch\n",
  610. "from torch import nn\n",
  611. "import torch.nn.functional as F\n",
  612. "\n",
  613. "class double_conv(nn.Module):\n",
  614. " def __init__(self, in_ch, out_ch):\n",
  615. " super(double_conv, self).__init__()\n",
  616. " self.conv = nn.Sequential(\n",
  617. " nn.Conv2d(in_ch, out_ch, 3, padding=1),\n",
  618. " nn.BatchNorm2d(out_ch),\n",
  619. " nn.ReLU(inplace=True),\n",
  620. " nn.Conv2d(out_ch, out_ch, 3, padding=1),\n",
  621. " nn.BatchNorm2d(out_ch),\n",
  622. " nn.ReLU(inplace=True)\n",
  623. " )\n",
  624. "\n",
  625. " def forward(self, x):\n",
  626. " x = self.conv(x)\n",
  627. " return x\n",
  628. "\n",
  629. "\n",
  630. "class up(nn.Module):\n",
  631. " def __init__(self, in_ch, out_ch):\n",
  632. " super(up, self).__init__()\n",
  633. " self.up_scale = nn.ConvTranspose2d(in_ch, out_ch, 2, stride=2)\n",
  634. "\n",
  635. " def forward(self, x1, x2):\n",
  636. " x2 = self.up_scale(x2)\n",
  637. "\n",
  638. " diffY = x1.size()[2] - x2.size()[2]\n",
  639. " diffX = x1.size()[3] - x2.size()[3]\n",
  640. "\n",
  641. " x2 = F.pad(x2, [diffX // 2, diffX - diffX // 2,\n",
  642. " diffY // 2, diffY - diffY // 2])\n",
  643. " x = torch.cat([x2, x1], dim=1)\n",
  644. " return x\n",
  645. "\n",
  646. "\n",
  647. "class down_layer(nn.Module):\n",
  648. " def __init__(self, in_ch, out_ch):\n",
  649. " super(down_layer, self).__init__()\n",
  650. " self.pool = nn.MaxPool2d(2, stride=2, padding=0)\n",
  651. " self.conv = double_conv(in_ch, out_ch)\n",
  652. "\n",
  653. " def forward(self, x):\n",
  654. " x = self.conv(self.pool(x))\n",
  655. " return x\n",
  656. "\n",
  657. "\n",
  658. "class up_layer(nn.Module):\n",
  659. " def __init__(self, in_ch, out_ch):\n",
  660. " super(up_layer, self).__init__()\n",
  661. " self.up = up(in_ch, out_ch)\n",
  662. " self.conv = double_conv(in_ch, out_ch)\n",
  663. "\n",
  664. " def forward(self, x1, x2):\n",
  665. " a = self.up(x1, x2)\n",
  666. " x = self.conv(a)\n",
  667. " return x\n",
  668. "\n",
  669. "\n",
  670. "class NewUnet(nn.Module):\n",
  671. " def __init__(self, dimensions=2):\n",
  672. " super(NewUnet, self).__init__()\n",
  673. " self.conv1 = double_conv(1, 64)\n",
  674. " self.down1 = down_layer(64, 128)\n",
  675. " self.down2 = down_layer(128, 256)\n",
  676. " self.down3 = down_layer(256, 512)\n",
  677. " self.down4 = down_layer(512, 1024)\n",
  678. " self.up1 = up_layer(1024, 512)\n",
  679. " self.up2 = up_layer(512, 256)\n",
  680. " self.up3 = up_layer(256, 128)\n",
  681. " self.up4 = up_layer(128, 64)\n",
  682. " self.last_conv = nn.Conv2d(64, dimensions, 1)\n",
  683. "\n",
  684. " def forward(self, x):\n",
  685. " x1 = self.conv1(x)\n",
  686. " x2 = self.down1(x1)\n",
  687. " x3 = self.down2(x2)\n",
  688. " x4 = self.down3(x3)\n",
  689. " x5 = self.down4(x4)\n",
  690. " x1_up = self.up1(x4, x5)\n",
  691. " x2_up = self.up2(x3, x1_up)\n",
  692. " x3_up = self.up3(x2, x2_up)\n",
  693. " x4_up = self.up4(x1, x3_up)\n",
  694. " output = self.last_conv(x4_up)\n",
  695. " return output"
  696. ]
  697. },
  698. {
  699. "cell_type": "code",
  700. "execution_count": 10,
  701. "metadata": {},
  702. "outputs": [],
  703. "source": [
  704. "from torch.utils.tensorboard import SummaryWriter\n",
  705. "import shutil\n",
  706. "\n",
  707. "shutil.rmtree('./runs/train')\n",
  708. "shutil.rmtree('./runs/val')\n",
  709. "\n",
  710. "os.mkdir('./runs/train')\n",
  711. "os.mkdir('./runs/val')\n",
  712. "\n",
  713. "trainWriter = SummaryWriter('runs/train')\n",
  714. "valWriter = SummaryWriter('runs/val')\n"
  715. ]
  716. },
  717. {
  718. "cell_type": "code",
  719. "execution_count": 11,
  720. "metadata": {},
  721. "outputs": [],
  722. "source": [
  723. "# import torch\n",
  724. "# import torch.nn as nn\n",
  725. "# import torch.nn.functional as F\n",
  726. "\n",
  727. "\n",
  728. "# class DiceLoss(nn.Module):\n",
  729. "\n",
  730. "# def __init__(self):\n",
  731. "# super(DiceLoss, self).__init__()\n",
  732. "# self.smooth = 1.0\n",
  733. "\n",
  734. "# def forward(self, y_pred, y_true):\n",
  735. "# assert y_pred.size() == y_true.size()\n",
  736. "# y_pred = y_pred[:, 0].contiguous().view(-1)\n",
  737. "# y_true = y_true[:, 0].contiguous().view(-1)\n",
  738. "# intersection = (y_pred * y_true).sum()\n",
  739. "# dsc = (2. * intersection + self.smooth) / (\n",
  740. "# y_pred.sum() + y_true.sum() + self.smooth\n",
  741. "# )\n",
  742. "# return 1. - dsc\n",
  743. "\n",
  744. "# class FocalLoss(nn.Module): \n",
  745. "# def __init__(self, weight=None, \n",
  746. "# gamma=2., reduction='none'):\n",
  747. "# nn.Module.__init__(self)\n",
  748. "# self.weight = weight\n",
  749. "# self.gamma = gamma\n",
  750. "# self.reduction = reduction\n",
  751. " \n",
  752. "# def forward(self, input_tensor, target_tensor):\n",
  753. " \n",
  754. "# target = target_tensor.long()\n",
  755. "# target = target.squeeze(1) \n",
  756. "# print(input_tensor.shape)\n",
  757. "# print(target_tensor.shape)\n",
  758. "# print(target.shape)\n",
  759. "# log_prob = F.log_softmax(input_tensor, dim=-1)\n",
  760. "# prob = torch.exp(log_prob)\n",
  761. "# return F.nll_loss(\n",
  762. "# ((1 - prob) ** self.gamma) * log_prob, \n",
  763. "# target, \n",
  764. "# weight=self.weight,\n",
  765. "# reduction = self.reduction\n",
  766. "# )"
  767. ]
  768. },
  769. {
  770. "cell_type": "code",
  771. "execution_count": 12,
  772. "metadata": {},
  773. "outputs": [],
  774. "source": [
  775. "# class BinaryFocalLoss(nn.Module):\n",
  776. "# \"\"\"\n",
  777. "# This is a implementation of Focal Loss with smooth label cross entropy supported which is proposed in\n",
  778. "# 'Focal Loss for Dense Object Detection. (https://arxiv.org/abs/1708.02002)'\n",
  779. "# Focal_Loss= -1*alpha*(1-pt)*log(pt)\n",
  780. "# :param alpha: (tensor) 3D or 4D the scalar factor for this criterion\n",
  781. "# :param gamma: (float,double) gamma > 0 reduces the relative loss for well-classified examples (p>0.5) putting more\n",
  782. "# focus on hard misclassified example\n",
  783. "# :param reduction: `none`|`mean`|`sum`\n",
  784. "# :param **kwargs\n",
  785. "# balance_index: (int) balance class index, should be specific when alpha is float\n",
  786. "# \"\"\"\n",
  787. "\n",
  788. "# def __init__(self, alpha=3, gamma=2, ignore_index=None, reduction='mean',**kwargs):\n",
  789. "# super(BinaryFocalLoss, self).__init__()\n",
  790. "# self.alpha = alpha\n",
  791. "# self.gamma = gamma\n",
  792. "# self.smooth = 1e-6 # set '1e-4' when train with FP16\n",
  793. "# self.ignore_index = ignore_index\n",
  794. "# self.reduction = reduction\n",
  795. "\n",
  796. "# assert self.reduction in ['none', 'mean', 'sum']\n",
  797. "\n",
  798. "# # if self.alpha is None:\n",
  799. "# # self.alpha = torch.ones(2)\n",
  800. "# # elif isinstance(self.alpha, (list, np.ndarray)):\n",
  801. "# # self.alpha = np.asarray(self.alpha)\n",
  802. "# # self.alpha = np.reshape(self.alpha, (2))\n",
  803. "# # assert self.alpha.shape[0] == 2, \\\n",
  804. "# # 'the `alpha` shape is not match the number of class'\n",
  805. "# # elif isinstance(self.alpha, (float, int)):\n",
  806. "# # self.alpha = np.asarray([self.alpha, 1.0 - self.alpha], dtype=np.float).view(2)\n",
  807. "\n",
  808. "# # else:\n",
  809. "# # raise TypeError('{} not supported'.format(type(self.alpha)))\n",
  810. "\n",
  811. "# def forward(self, output, target):\n",
  812. "# prob = torch.sigmoid(output)\n",
  813. "# prob = torch.clamp(prob, self.smooth, 1.0 - self.smooth)\n",
  814. "\n",
  815. "# valid_mask = None\n",
  816. "# if self.ignore_index is not None:\n",
  817. "# valid_mask = (target != self.ignore_index).float()\n",
  818. "\n",
  819. "# pos_mask = (target == 1).float()\n",
  820. "# neg_mask = (target == 0).float()\n",
  821. "# if valid_mask is not None:\n",
  822. "# pos_mask = pos_mask * valid_mask\n",
  823. "# neg_mask = neg_mask * valid_mask\n",
  824. "\n",
  825. "# pos_weight = (pos_mask * torch.pow(1 - prob, self.gamma)).detach()\n",
  826. "# pos_loss = -torch.sum(pos_weight * torch.log(prob)) / (torch.sum(pos_weight) + 1e-4)\n",
  827. " \n",
  828. " \n",
  829. "# neg_weight = (neg_mask * torch.pow(prob, self.gamma)).detach()\n",
  830. "# neg_loss = -self.alpha * torch.sum(neg_weight * F.logsigmoid(-output)) / (torch.sum(neg_weight) + 1e-4)\n",
  831. "# loss = pos_loss + neg_loss\n",
  832. "\n",
  833. "# return loss\n",
  834. "\n",
  835. "\n",
  836. "\n",
  837. "# class FocalLoss_Ori(nn.Module):\n",
  838. "# \"\"\"\n",
  839. "# This is a implementation of Focal Loss with smooth label cross entropy supported which is proposed in\n",
  840. "# 'Focal Loss for Dense Object Detection. (https://arxiv.org/abs/1708.02002)'\n",
  841. "# Focal_Loss= -1*alpha*(1-pt)*log(pt)\n",
  842. "# :param num_class:\n",
  843. "# :param alpha: (tensor) 3D or 4D the scalar factor for this criterion\n",
  844. "# :param gamma: (float,double) gamma > 0 reduces the relative loss for well-classified examples (p>0.5) putting more\n",
  845. "# focus on hard misclassified example\n",
  846. "# :param smooth: (float,double) smooth value when cross entropy\n",
  847. "# :param size_average: (bool, optional) By default, the losses are averaged over each loss element in the batch.\n",
  848. "# \"\"\"\n",
  849. "\n",
  850. "# def __init__(self, num_class, alpha=[0.25,0.75], gamma=2, balance_index=-1, size_average=True):\n",
  851. "# super(FocalLoss_Ori, self).__init__()\n",
  852. "# self.num_class = num_class\n",
  853. "# self.alpha = alpha\n",
  854. "# self.gamma = gamma\n",
  855. "# self.size_average = size_average\n",
  856. "# self.eps = 1e-6\n",
  857. "\n",
  858. "# if isinstance(self.alpha, (list, tuple)):\n",
  859. "# assert len(self.alpha) == self.num_class\n",
  860. "# self.alpha = torch.Tensor(list(self.alpha))\n",
  861. "# elif isinstance(self.alpha, (float,int)):\n",
  862. "# assert 0 < self.alpha < 1.0, 'alpha should be in `(0,1)`)'\n",
  863. "# assert balance_index > -1\n",
  864. "# alpha = torch.ones((self.num_class))\n",
  865. "# alpha *= 1-self.alpha\n",
  866. "# alpha[balance_index] = self.alpha\n",
  867. "# self.alpha = alpha\n",
  868. "# elif isinstance(self.alpha, torch.Tensor):\n",
  869. "# self.alpha = self.alpha\n",
  870. "# else:\n",
  871. "# raise TypeError('Not support alpha type, expect `int|float|list|tuple|torch.Tensor`')\n",
  872. "\n",
  873. "# def forward(self, logit, target):\n",
  874. "\n",
  875. "# if logit.dim() > 2:\n",
  876. "# # N,C,d1,d2 -> N,C,m (m=d1*d2*...)\n",
  877. "# logit = logit.view(logit.size(0), logit.size(1), -1)\n",
  878. "# logit = logit.transpose(1, 2).contiguous() # [N,C,d1*d2..] -> [N,d1*d2..,C]\n",
  879. "# logit = logit.view(-1, logit.size(-1)) # [N,d1*d2..,C]-> [N*d1*d2..,C]\n",
  880. "# target = target.view(-1, 1) # [N,d1,d2,...]->[N*d1*d2*...,1]\n",
  881. "\n",
  882. "# # -----------legacy way------------\n",
  883. "# # idx = target.cpu().long()\n",
  884. "# # one_hot_key = torch.FloatTensor(target.size(0), self.num_class).zero_()\n",
  885. "# # one_hot_key = one_hot_key.scatter_(1, idx, 1)\n",
  886. "# # if one_hot_key.device != logit.device:\n",
  887. "# # one_hot_key = one_hot_key.to(logit.device)\n",
  888. "# # pt = (one_hot_key * logit).sum(1) + epsilon\n",
  889. "\n",
  890. "# # ----------memory saving way--------\n",
  891. "# pt = logit.gather(1, target).view(-1) + self.eps # avoid apply\n",
  892. "# logpt = pt.log()\n",
  893. "\n",
  894. "# if self.alpha.device != logpt.device:\n",
  895. "# alpha = self.alpha.to(logpt.device)\n",
  896. "# alpha_class = alpha.gather(0,target.view(-1))\n",
  897. "# logpt = alpha_class*logpt\n",
  898. "# loss = -1 * torch.pow(torch.sub(1.0, pt), self.gamma) * logpt\n",
  899. "\n",
  900. "# if self.size_average:\n",
  901. "# loss = loss.mean()\n",
  902. "# else:\n",
  903. "# loss = loss.sum()\n",
  904. "# return loss"
  905. ]
  906. },
  907. {
  908. "cell_type": "code",
  909. "execution_count": 13,
  910. "metadata": {},
  911. "outputs": [],
  912. "source": [
  913. "# class FocalLoss(nn.Module):\n",
  914. "# def __init__(self, alpha=1, gamma=2, logits=False, reduce=True):\n",
  915. "# super(FocalLoss, self).__init__()\n",
  916. "# self.alpha = alpha\n",
  917. "# self.gamma = gamma\n",
  918. "# self.logits = logits\n",
  919. "# self.reduce = reduce\n",
  920. "\n",
  921. "# def forward(self, inputs, targets):\n",
  922. "# if self.logits:\n",
  923. "# BCE_loss = F.binary_cross_entropy_with_logits(inputs, targets, reduce=False)\n",
  924. "# else:\n",
  925. "# BCE_loss = F.binary_cross_entropy(inputs, targets, reduce=False)\n",
  926. "# pt = torch.exp(-BCE_loss)\n",
  927. "# F_loss = self.alpha * (1-pt)**self.gamma * BCE_loss\n",
  928. "\n",
  929. "# if self.reduce:\n",
  930. "# return torch.mean(F_loss)\n",
  931. "# else:\n",
  932. "# return F_loss"
  933. ]
  934. },
  935. {
  936. "cell_type": "code",
  937. "execution_count": 14,
  938. "metadata": {},
  939. "outputs": [],
  940. "source": [
  941. "\n",
  942. "# from collections import defaultdict\n",
  943. "# import torch.nn.functional as F\n",
  944. "# from loss import dice_loss\n",
  945. "\n",
  946. "# def calc_loss(pred, target, metrics, bce_weight=0.5):\n",
  947. "# bce = F.binary_cross_entropy_with_logits(pred, target)\n",
  948. " \n",
  949. "# pred = F.sigmoid(pred)\n",
  950. "# dice = dice_loss(pred, target)\n",
  951. " \n",
  952. "# loss = bce * bce_weight + dice * (1 - bce_weight)\n",
  953. " \n",
  954. "# metrics['bce'] += bce.data.cpu().numpy() * target.size(0)\n",
  955. "# metrics['dice'] += dice.data.cpu().numpy() * target.size(0)\n",
  956. "# metrics['loss'] += loss.data.cpu().numpy() * target.size(0)\n",
  957. " \n",
  958. "# return loss\n",
  959. "\n",
  960. "# def print_metrics(metrics, epoch_samples, phase): \n",
  961. "# outputs = []\n",
  962. "# for k in metrics.keys():\n",
  963. "# outputs.append(\"{}: {:4f}\".format(k, metrics[k] / epoch_samples))\n",
  964. " \n",
  965. "# print(\"{}: {}\".format(phase, \", \".join(outputs))) \n",
  966. "\n",
  967. "\n",
  968. "# def get_loss_tb(metrics, epoch_samples, phase):\n",
  969. "# loss = metrics['loss']\n",
  970. "# return loss\n",
  971. " \n",
  972. "# def train_model(model, optimizer, scheduler, num_epochs=25):\n",
  973. "# best_model_wts = copy.deepcopy(model.state_dict())\n",
  974. "# best_loss = 1e10\n",
  975. " \n",
  976. "# dsc_loss = DiceLoss()\n",
  977. "# # dsc_loss = FocalLoss()\n",
  978. "\n",
  979. "# loss_train = []\n",
  980. "# loss_valid = []\n",
  981. "# step = 0\n",
  982. " \n",
  983. "# for epoch in range(num_epochs):\n",
  984. "# print('Epoch {}/{}'.format(epoch, num_epochs - 1))\n",
  985. "# print('-' * 10)\n",
  986. " \n",
  987. "# print(model.encoder1[0].weight[0])\n",
  988. "# # print(model.dconv_down1[0].weight.grad)\n",
  989. "# # print(model.dconv_down1[0].weight[0])\n",
  990. "# # print(model.module.down1.maxpool_conv[1].double_conv[0].weight[0][0])\n",
  991. " \n",
  992. "# # dconv_down1\n",
  993. "# since = time.time()\n",
  994. " \n",
  995. " \n",
  996. "# # Each epoch has a training and validation phase\n",
  997. "# for phase in ['train', 'val']:\n",
  998. "# if phase == 'train':\n",
  999. "# scheduler.step()\n",
  1000. "# for param_group in optimizer.param_groups:\n",
  1001. "# print(\"LR\", param_group['lr'])\n",
  1002. " \n",
  1003. "# model.train() # Set model to training mode\n",
  1004. "# else:\n",
  1005. "# model.eval() # Set model to evaluate mode\n",
  1006. "\n",
  1007. "# metrics = defaultdict(float)\n",
  1008. "# epoch_samples = 0\n",
  1009. " \n",
  1010. "# dtype = torch.cuda.FloatTensor if torch.cuda.is_available() else torch.FloatTensor\n",
  1011. " \n",
  1012. "# for inputs, labels in dataloaders[phase]:\n",
  1013. " \n",
  1014. "# if phase == 'train':\n",
  1015. "# step += 1\n",
  1016. "# inputs = inputs.to(device, dtype=torch.float)\n",
  1017. "# labels = labels.to(device, dtype=torch.float)\n",
  1018. "# # inputs = inputs.to(device)\n",
  1019. "# # labels = labels.to(device)\n",
  1020. "\n",
  1021. "# # zero the parameter gradients\n",
  1022. "# optimizer.zero_grad()\n",
  1023. "\n",
  1024. "# # forward\n",
  1025. "# # track history if only in train\n",
  1026. "# with torch.set_grad_enabled(phase == 'train'):\n",
  1027. "# outputs = model(inputs)\n",
  1028. "# # loss = calc_loss(outputs, labels, metrics)\n",
  1029. "# loss = dsc_loss(outputs, labels)\n",
  1030. "\n",
  1031. "# # backward + optimize only if in training phase\n",
  1032. "# if phase == 'train':\n",
  1033. "# loss_train.append(loss.item())\n",
  1034. "# loss.backward()\n",
  1035. "# # print(loss.grad)\n",
  1036. "# optimizer.step()\n",
  1037. " \n",
  1038. "# # print(\"hello\")\n",
  1039. "# # print(loss)\n",
  1040. "# print(\"step: \" + str(step))\n",
  1041. "# if phase == \"train\" and (step + 1) % 20 == 0:\n",
  1042. "# # log_loss_summary(logger, loss_train, step)\n",
  1043. "# print(\"epoch: \" + str(epoch) + \"phase: \" + phase + \" step: \" + str(step) + \" loss: \" + str(np.mean(loss_train)))\n",
  1044. "# loss_train = []\n",
  1045. "# # statistics\n",
  1046. "# epoch_samples += inputs.size(0)\n",
  1047. "\n",
  1048. "# # print_metrics(metrics, epoch_samples, phase)\n",
  1049. "# # print(phase + \": \" + str(loss))\n",
  1050. "# epoch_loss = metrics['loss'] / epoch_samples\n",
  1051. " \n",
  1052. "# if phase == 'train':\n",
  1053. "# trainWriter.add_scalar('Loss',\n",
  1054. "# epoch_loss,\n",
  1055. "# epoch)\n",
  1056. "# elif phase == 'val':\n",
  1057. "# valWriter.add_scalar('Loss',\n",
  1058. "# epoch_loss,\n",
  1059. "# epoch)\n",
  1060. "# # deep copy the model\n",
  1061. "# if phase == 'val' and epoch_loss < best_loss:\n",
  1062. "# print(\"saving best model\")\n",
  1063. "# best_loss = epoch_loss\n",
  1064. "# best_model_wts = copy.deepcopy(model.state_dict())\n",
  1065. "\n",
  1066. "# time_elapsed = time.time() - since\n",
  1067. "# print('{:.0f}m {:.0f}s'.format(time_elapsed // 60, time_elapsed % 60))\n",
  1068. "# # print(metrics)\n",
  1069. "# # writer.add_scalar('val loss',\n",
  1070. "# # running_loss / 1000,\n",
  1071. "# # epoch)\n",
  1072. " \n",
  1073. "# print('Best val loss: {:4f}'.format(best_loss))\n",
  1074. "\n",
  1075. "# # load best model weights\n",
  1076. "# model.load_state_dict(best_model_wts)\n",
  1077. "# return model"
  1078. ]
  1079. },
  1080. {
  1081. "cell_type": "code",
  1082. "execution_count": 15,
  1083. "metadata": {},
  1084. "outputs": [],
  1085. "source": [
  1086. "def focalLoss(inputs, targets, alpha=1, gamma=1, logits=True, reduce=True):\n",
  1087. " if logits:\n",
  1088. " BCE_loss = F.binary_cross_entropy_with_logits(inputs, targets, reduce=False)\n",
  1089. " else:\n",
  1090. " BCE_loss = F.binary_cross_entropy(inputs, targets, reduce=False)\n",
  1091. " pt = torch.exp(-BCE_loss)\n",
  1092. " F_loss = alpha * (1-pt)**gamma * BCE_loss\n",
  1093. "\n",
  1094. " if reduce:\n",
  1095. " return torch.mean(F_loss)\n",
  1096. " else:\n",
  1097. " return F_loss\n",
  1098. "\n",
  1099. "def calc_loss(pred, target, metrics, bce_weight=0.5):\n",
  1100. " bce = F.binary_cross_entropy_with_logits(pred, target)\n",
  1101. " dice = dice_loss(pred, target)\n",
  1102. "# loss = bce * bce_weight + dice * (1 - bce_weight)\n",
  1103. " loss = focalLoss(pred, target)\n",
  1104. " metrics['bce'] += bce.data.cpu().numpy() * target.size(0)\n",
  1105. " metrics['dice'] += dice.data.cpu().numpy() * target.size(0)\n",
  1106. " metrics['loss'] += loss.data.cpu().numpy() * target.size(0)\n",
  1107. " \n",
  1108. " return loss\n"
  1109. ]
  1110. },
  1111. {
  1112. "cell_type": "code",
  1113. "execution_count": 16,
  1114. "metadata": {},
  1115. "outputs": [],
  1116. "source": [
  1117. "# # Default_loss_function\n",
  1118. "# def calc_loss(pred, target, metrics, bce_weight=0.5):\n",
  1119. "# bce = F.binary_cross_entropy_with_logits(pred, target)\n",
  1120. "# # bce = torch.nn.CrossEntropyLoss(pred, target)\n",
  1121. " \n",
  1122. "# # bce = F.binary_cross_entropy(pred, target)\n",
  1123. "# # loss_nll = nn.NLLLoss2d()\n",
  1124. "# # loss1 = loss_nll(F.log_softmax(input1), target)\n",
  1125. "# # loss = loss_nll(F.log_softmax(pred), target)\n",
  1126. "\n",
  1127. "# # pred = F.sigmoid(pred)\n",
  1128. "# dice = dice_loss(pred, target)\n",
  1129. " \n",
  1130. "# loss = bce * bce_weight + dice * (1 - bce_weight)\n",
  1131. " \n",
  1132. "# metrics['bce'] += bce.data.cpu().numpy() * target.size(0)\n",
  1133. "# metrics['dice'] += dice.data.cpu().numpy() * target.size(0)\n",
  1134. "# metrics['loss'] += loss.data.cpu().numpy() * target.size(0)\n",
  1135. " \n",
  1136. "# return loss\n"
  1137. ]
  1138. },
  1139. {
  1140. "cell_type": "code",
  1141. "execution_count": 17,
  1142. "metadata": {},
  1143. "outputs": [],
  1144. "source": [
  1145. "\n",
  1146. "\n",
  1147. "from collections import defaultdict\n",
  1148. "import torch.nn.functional as F\n",
  1149. "from loss import dice_loss\n",
  1150. "\n",
  1151. "\n",
  1152. "def print_metrics(metrics, epoch_samples, phase): \n",
  1153. " outputs = []\n",
  1154. " for k in metrics.keys():\n",
  1155. " outputs.append(\"{}: {:4f}\".format(k, metrics[k] / epoch_samples))\n",
  1156. " \n",
  1157. " print(\"{}: {}\".format(phase, \", \".join(outputs))) \n",
  1158. "\n",
  1159. "\n",
  1160. "def get_loss_tb(metrics, epoch_samples, phase):\n",
  1161. " loss = metrics['loss']\n",
  1162. " return loss\n",
  1163. " \n",
  1164. "def print_pred(output):\n",
  1165. " img = output.data.cpu().numpy()\n",
  1166. "\n",
  1167. " print(\"min max:\")\n",
  1168. " print(np.amin(img), np.amax(img))\n",
  1169. "# print(np.amax(img))\n",
  1170. " print(\"sum\")\n",
  1171. " print(img.sum())\n",
  1172. " \n",
  1173. " \n",
  1174. "def train_model(model, optimizer, scheduler, num_epochs=25, load_model=False):\n",
  1175. " best_model_wts = copy.deepcopy(model.state_dict())\n",
  1176. " best_loss = 1e10\n",
  1177. "\n",
  1178. " if load_model:\n",
  1179. " model.load_state_dict(torch.load('./best_model.pt'))\n",
  1180. " \n",
  1181. " \n",
  1182. "# FL = FocalLoss()\n",
  1183. "# FL = FocalLoss(n)\n",
  1184. "# FL = FocalLoss_Ori(num_class=2)\n",
  1185. "# FL = FocalLoss_Ori(num_class=2, alpha=0.25,\n",
  1186. "# gamma=2.0, balance_index=2)\n",
  1187. " \n",
  1188. " for epoch in range(num_epochs):\n",
  1189. " print('\\n\\nEpoch {}/{}'.format(epoch, num_epochs - 1))\n",
  1190. " print('-' * 10)\n",
  1191. " \n",
  1192. "# print(model.encoder1[0].weight[0])\n",
  1193. "# print(model.dconv_down1[0].weight.grad)\n",
  1194. "# print(model.dconv_down1[0].weight[0])\n",
  1195. "# print(model.module.down1.maxpool_conv[1].double_conv[0].weight[0][0])\n",
  1196. " \n",
  1197. " \n",
  1198. "# print(model.decoder1[4].weight)\n",
  1199. "# dconv_down1\n",
  1200. " since = time.time()\n",
  1201. " \n",
  1202. " \n",
  1203. " # Each epoch has a training and validation phase\n",
  1204. " for phase in ['train', 'val']:\n",
  1205. " if phase == 'train':\n",
  1206. " scheduler.step()\n",
  1207. " for param_group in optimizer.param_groups:\n",
  1208. " print(\"LR\", param_group['lr'])\n",
  1209. " \n",
  1210. " model.train() # Set model to training mode\n",
  1211. " else:\n",
  1212. " model.eval() # Set model to evaluate mode\n",
  1213. "\n",
  1214. " metrics = defaultdict(float)\n",
  1215. " epoch_samples = 0\n",
  1216. " \n",
  1217. " dtype = torch.cuda.FloatTensor if torch.cuda.is_available() else torch.FloatTensor\n",
  1218. " \n",
  1219. " for inputs, labels in dataloaders[phase]:\n",
  1220. "# inputs = inputs.to(device, dtype=torch.float)\n",
  1221. "# labels = labels.to(device, dtype=torch.float)\n",
  1222. "# inputs = inputs.to(device).type(dtype)\n",
  1223. "# labels = labels.to(device).type(dtype)\n",
  1224. "\n",
  1225. " inputs = inputs.to(device)\n",
  1226. " labels = labels.to(device)\n",
  1227. "\n",
  1228. " # zero the parameter gradients\n",
  1229. " optimizer.zero_grad()\n",
  1230. "\n",
  1231. " # forward\n",
  1232. " # track history if only in train\n",
  1233. " with torch.set_grad_enabled(phase == 'train'):\n",
  1234. " outputs = model(inputs)\n",
  1235. " loss = calc_loss(outputs, labels, metrics)\n",
  1236. " \n",
  1237. "# loss = FL(outputs, labels)\n",
  1238. "# print(type(loss))\n",
  1239. "# print(loss.shape)\n",
  1240. " # backward + optimize only if in training phase\n",
  1241. " if phase == 'train':\n",
  1242. "# print('loss.item:\\n')\n",
  1243. "# print()\n",
  1244. " loss.backward()\n",
  1245. "# print(loss.grad)\n",
  1246. " optimizer.step()\n",
  1247. " \n",
  1248. "# print(\"hello\")\n",
  1249. "# print(loss)\n",
  1250. "\n",
  1251. "\n",
  1252. " # statistics\n",
  1253. " epoch_samples += inputs.size(0)\n",
  1254. "\n",
  1255. " print_metrics(metrics, epoch_samples, phase)\n",
  1256. " epoch_loss = metrics['loss'] / epoch_samples\n",
  1257. " \n",
  1258. " if phase == 'train':\n",
  1259. " trainWriter.add_scalar('Loss',\n",
  1260. " epoch_loss,\n",
  1261. " epoch)\n",
  1262. " elif phase == 'val':\n",
  1263. " valWriter.add_scalar('Loss',\n",
  1264. " epoch_loss,\n",
  1265. " epoch)\n",
  1266. " # deep copy the model\n",
  1267. " if phase == 'val' and epoch_loss < best_loss:\n",
  1268. " print(\"saving best model\")\n",
  1269. " best_loss = epoch_loss\n",
  1270. " best_model_wts = copy.deepcopy(model.state_dict())\n",
  1271. " torch.save(model.state_dict(), './best_model.pt')\n",
  1272. "\n",
  1273. " time_elapsed = time.time() - since\n",
  1274. " print('{:.0f}m {:.0f}s'.format(time_elapsed // 60, time_elapsed % 60))\n",
  1275. "# print(metrics)\n",
  1276. "# writer.add_scalar('val loss',\n",
  1277. "# running_loss / 1000,\n",
  1278. "# epoch)\n",
  1279. " \n",
  1280. " print('Best val loss: {:4f}'.format(best_loss))\n",
  1281. "\n",
  1282. " # load best model weights\n",
  1283. " model.load_state_dict(best_model_wts)\n",
  1284. " return model"
  1285. ]
  1286. },
  1287. {
  1288. "cell_type": "code",
  1289. "execution_count": null,
  1290. "metadata": {},
  1291. "outputs": [],
  1292. "source": []
  1293. },
  1294. {
  1295. "cell_type": "code",
  1296. "execution_count": 18,
  1297. "metadata": {
  1298. "scrolled": true
  1299. },
  1300. "outputs": [
  1301. {
  1302. "name": "stdout",
  1303. "output_type": "stream",
  1304. "text": [
  1305. "cuda:1\n",
  1306. "True\n",
  1307. "\n",
  1308. "\n",
  1309. "Epoch 0/799\n",
  1310. "----------\n",
  1311. "LR 0.0001\n"
  1312. ]
  1313. },
  1314. {
  1315. "name": "stderr",
  1316. "output_type": "stream",
  1317. "text": [
  1318. "/home/rasekh/.local/lib/python3.5/site-packages/torch/nn/_reduction.py:46: UserWarning: size_average and reduce args will be deprecated, please use reduction='none' instead.\n",
  1319. " warnings.warn(warning.format(ret))\n"
  1320. ]
  1321. },
  1322. {
  1323. "name": "stdout",
  1324. "output_type": "stream",
  1325. "text": [
  1326. "train: loss: 0.071897, bce: 0.076008, dice: 0.999324\n",
  1327. "val: loss: 0.306743, bce: 0.644317, dice: 1.009425\n",
  1328. "saving best model\n",
  1329. "0m 9s\n",
  1330. "\n",
  1331. "\n",
  1332. "Epoch 1/799\n",
  1333. "----------\n",
  1334. "LR 0.0001\n",
  1335. "train: loss: 0.079999, bce: 0.176136, dice: 1.000632\n",
  1336. "val: loss: 0.003854, bce: 0.017278, dice: 0.998829\n",
  1337. "saving best model\n",
  1338. "0m 8s\n",
  1339. "\n",
  1340. "\n",
  1341. "Epoch 2/799\n",
  1342. "----------\n",
  1343. "LR 0.0001\n",
  1344. "train: loss: 0.003582, bce: 0.015781, dice: 0.998975\n",
  1345. "val: loss: 0.003774, bce: 0.011886, dice: 0.998861\n",
  1346. "saving best model\n",
  1347. "0m 8s\n",
  1348. "\n",
  1349. "\n",
  1350. "Epoch 3/799\n",
  1351. "----------\n",
  1352. "LR 0.0001\n",
  1353. "train: loss: 0.003246, bce: 0.013095, dice: 0.999064\n",
  1354. "val: loss: 0.003168, bce: 0.013453, dice: 0.999186\n",
  1355. "saving best model\n",
  1356. "0m 8s\n",
  1357. "\n",
  1358. "\n",
  1359. "Epoch 4/799\n",
  1360. "----------\n",
  1361. "LR 0.0001\n",
  1362. "train: loss: 0.003923, bce: 0.016950, dice: 0.999210\n",
  1363. "val: loss: 0.005839, bce: 0.007567, dice: 0.998680\n",
  1364. "0m 8s\n",
  1365. "\n",
  1366. "\n",
  1367. "Epoch 5/799\n",
  1368. "----------\n",
  1369. "LR 0.0001\n",
  1370. "train: loss: 0.003537, bce: 0.010286, dice: 0.999067\n",
  1371. "val: loss: 0.003171, bce: 0.011245, dice: 0.999114\n",
  1372. "0m 8s\n",
  1373. "\n",
  1374. "\n",
  1375. "Epoch 6/799\n",
  1376. "----------\n",
  1377. "LR 0.0001\n",
  1378. "train: loss: 0.002956, bce: 0.011612, dice: 0.999179\n",
  1379. "val: loss: 0.002927, bce: 0.013787, dice: 0.999311\n",
  1380. "saving best model\n",
  1381. "0m 9s\n",
  1382. "\n",
  1383. "\n",
  1384. "Epoch 7/799\n",
  1385. "----------\n",
  1386. "LR 0.0001\n",
  1387. "train: loss: 0.002784, bce: 0.011852, dice: 0.999293\n",
  1388. "val: loss: 0.002957, bce: 0.009062, dice: 0.999179\n",
  1389. "0m 9s\n",
  1390. "\n",
  1391. "\n",
  1392. "Epoch 8/799\n",
  1393. "----------\n",
  1394. "LR 0.0001\n",
  1395. "train: loss: 0.002549, bce: 0.011070, dice: 0.999340\n",
  1396. "val: loss: 0.003910, bce: 0.006232, dice: 0.998974\n",
  1397. "0m 9s\n",
  1398. "\n",
  1399. "\n",
  1400. "Epoch 9/799\n",
  1401. "----------\n",
  1402. "LR 0.0001\n",
  1403. "train: loss: 0.003529, bce: 0.012275, dice: 0.999210\n",
  1404. "val: loss: 0.002714, bce: 0.010829, dice: 0.999249\n",
  1405. "saving best model\n",
  1406. "0m 9s\n",
  1407. "\n",
  1408. "\n",
  1409. "Epoch 10/799\n",
  1410. "----------\n",
  1411. "LR 0.0001\n",
  1412. "train: loss: 0.002384, bce: 0.010921, dice: 0.999352\n",
  1413. "val: loss: 0.002877, bce: 0.008249, dice: 0.999123\n",
  1414. "0m 9s\n",
  1415. "\n",
  1416. "\n",
  1417. "Epoch 11/799\n",
  1418. "----------\n",
  1419. "LR 0.0001\n",
  1420. "train: loss: 0.002122, bce: 0.008885, dice: 0.999422\n",
  1421. "val: loss: 0.002338, bce: 0.018231, dice: 0.999663\n",
  1422. "saving best model\n",
  1423. "0m 9s\n",
  1424. "\n",
  1425. "\n",
  1426. "Epoch 12/799\n",
  1427. "----------\n",
  1428. "LR 0.0001\n",
  1429. "train: loss: 0.002430, bce: 0.011536, dice: 0.999464\n",
  1430. "val: loss: 0.002067, bce: 0.008582, dice: 0.999548\n",
  1431. "saving best model\n",
  1432. "0m 9s\n",
  1433. "\n",
  1434. "\n",
  1435. "Epoch 13/799\n",
  1436. "----------\n",
  1437. "LR 0.0001\n",
  1438. "train: loss: 0.001865, bce: 0.008732, dice: 0.999581\n",
  1439. "val: loss: 0.002762, bce: 0.008200, dice: 0.999153\n",
  1440. "0m 9s\n",
  1441. "\n",
  1442. "\n",
  1443. "Epoch 14/799\n",
  1444. "----------\n",
  1445. "LR 0.0001\n",
  1446. "train: loss: 0.001687, bce: 0.008645, dice: 0.999581\n",
  1447. "val: loss: 0.001515, bce: 0.007237, dice: 0.999887\n",
  1448. "saving best model\n",
  1449. "0m 9s\n",
  1450. "\n",
  1451. "\n",
  1452. "Epoch 15/799\n",
  1453. "----------\n",
  1454. "LR 0.0001\n",
  1455. "train: loss: 0.001656, bce: 0.007952, dice: 0.999656\n",
  1456. "val: loss: 0.001813, bce: 0.015488, dice: 0.999947\n",
  1457. "0m 9s\n",
  1458. "\n",
  1459. "\n",
  1460. "Epoch 16/799\n",
  1461. "----------\n",
  1462. "LR 0.0001\n",
  1463. "train: loss: 0.002156, bce: 0.010403, dice: 0.999598\n",
  1464. "val: loss: 0.001639, bce: 0.009729, dice: 0.999849\n",
  1465. "0m 9s\n",
  1466. "\n",
  1467. "\n",
  1468. "Epoch 17/799\n",
  1469. "----------\n",
  1470. "LR 0.0001\n",
  1471. "train: loss: 0.001417, bce: 0.008512, dice: 0.999742\n",
  1472. "val: loss: 0.001432, bce: 0.005983, dice: 0.999913\n",
  1473. "saving best model\n",
  1474. "0m 9s\n",
  1475. "\n",
  1476. "\n",
  1477. "Epoch 18/799\n",
  1478. "----------\n",
  1479. "LR 0.0001\n",
  1480. "train: loss: 0.001160, bce: 0.006083, dice: 0.999883\n",
  1481. "val: loss: 0.001193, bce: 0.006689, dice: 1.000627\n",
  1482. "saving best model\n",
  1483. "0m 9s\n",
  1484. "\n",
  1485. "\n",
  1486. "Epoch 19/799\n",
  1487. "----------\n",
  1488. "LR 0.0001\n",
  1489. "train: loss: 0.001530, bce: 0.006533, dice: 0.999979\n",
  1490. "val: loss: 0.001071, bce: 0.005101, dice: 1.000539\n",
  1491. "saving best model\n",
  1492. "0m 9s\n",
  1493. "\n",
  1494. "\n",
  1495. "Epoch 20/799\n",
  1496. "----------\n",
  1497. "LR 0.0001\n",
  1498. "train: loss: 0.001009, bce: 0.004980, dice: 1.000147\n",
  1499. "val: loss: 0.000854, bce: 0.003162, dice: 1.000955\n",
  1500. "saving best model\n",
  1501. "0m 9s\n",
  1502. "\n",
  1503. "\n",
  1504. "Epoch 21/799\n",
  1505. "----------\n",
  1506. "LR 0.0001\n",
  1507. "train: loss: 0.001396, bce: 0.006085, dice: 1.000400\n",
  1508. "val: loss: 0.008671, bce: 0.009508, dice: 0.998112\n",
  1509. "0m 9s\n",
  1510. "\n",
  1511. "\n",
  1512. "Epoch 22/799\n",
  1513. "----------\n",
  1514. "LR 0.0001\n",
  1515. "train: loss: 0.002213, bce: 0.008195, dice: 0.999523\n",
  1516. "val: loss: 0.001126, bce: 0.005387, dice: 1.000224\n",
  1517. "0m 9s\n",
  1518. "\n",
  1519. "\n",
  1520. "Epoch 23/799\n",
  1521. "----------\n",
  1522. "LR 0.0001\n",
  1523. "train: loss: 0.001056, bce: 0.005376, dice: 1.000006\n",
  1524. "val: loss: 0.000982, bce: 0.003616, dice: 1.000368\n",
  1525. "0m 9s\n",
  1526. "\n",
  1527. "\n",
  1528. "Epoch 24/799\n",
  1529. "----------\n",
  1530. "LR 0.0001\n",
  1531. "train: loss: 0.000986, bce: 0.005949, dice: 1.000130\n",
  1532. "val: loss: 0.001073, bce: 0.003197, dice: 1.000282\n",
  1533. "0m 9s\n",
  1534. "\n",
  1535. "\n",
  1536. "Epoch 25/799\n",
  1537. "----------\n",
  1538. "LR 0.0001\n",
  1539. "train: loss: 0.000849, bce: 0.003531, dice: 1.000200\n",
  1540. "val: loss: 0.000826, bce: 0.002912, dice: 1.000669\n",
  1541. "saving best model\n",
  1542. "0m 9s\n",
  1543. "\n",
  1544. "\n",
  1545. "Epoch 26/799\n",
  1546. "----------\n",
  1547. "LR 0.0001\n",
  1548. "train: loss: 0.000768, bce: 0.003208, dice: 1.000258\n",
  1549. "val: loss: 0.000750, bce: 0.002606, dice: 1.000884\n",
  1550. "saving best model\n",
  1551. "0m 9s\n",
  1552. "\n",
  1553. "\n",
  1554. "Epoch 27/799\n",
  1555. "----------\n",
  1556. "LR 0.0001\n",
  1557. "train: loss: 0.000855, bce: 0.004148, dice: 1.000379\n",
  1558. "val: loss: 0.000778, bce: 0.002888, dice: 1.000940\n",
  1559. "0m 9s\n",
  1560. "\n",
  1561. "\n",
  1562. "Epoch 28/799\n",
  1563. "----------\n",
  1564. "LR 0.0001\n",
  1565. "train: loss: 0.000695, bce: 0.002763, dice: 1.000342\n",
  1566. "val: loss: 0.000740, bce: 0.002772, dice: 1.001198\n",
  1567. "saving best model\n",
  1568. "0m 9s\n",
  1569. "\n",
  1570. "\n",
  1571. "Epoch 29/799\n",
  1572. "----------\n",
  1573. "LR 0.0001\n",
  1574. "train: loss: 0.000675, bce: 0.002509, dice: 1.000417\n",
  1575. "val: loss: 0.000662, bce: 0.002166, dice: 1.000914\n",
  1576. "saving best model\n",
  1577. "0m 9s\n",
  1578. "\n",
  1579. "\n",
  1580. "Epoch 30/799\n",
  1581. "----------\n",
  1582. "LR 0.0001\n",
  1583. "train: loss: 0.000602, bce: 0.002546, dice: 1.000426\n",
  1584. "val: loss: 0.000648, bce: 0.001743, dice: 1.001007\n",
  1585. "saving best model\n",
  1586. "0m 9s\n",
  1587. "\n",
  1588. "\n",
  1589. "Epoch 31/799\n",
  1590. "----------\n",
  1591. "LR 0.0001\n",
  1592. "train: loss: 0.000628, bce: 0.002308, dice: 1.000457\n",
  1593. "val: loss: 0.000924, bce: 0.002899, dice: 1.001475\n",
  1594. "0m 9s\n",
  1595. "\n",
  1596. "\n",
  1597. "Epoch 32/799\n",
  1598. "----------\n",
  1599. "LR 0.0001\n",
  1600. "train: loss: 0.000741, bce: 0.002228, dice: 1.000472\n",
  1601. "val: loss: 0.000774, bce: 0.003057, dice: 1.001135\n",
  1602. "0m 9s\n",
  1603. "\n",
  1604. "\n",
  1605. "Epoch 33/799\n",
  1606. "----------\n",
  1607. "LR 0.0001\n",
  1608. "train: loss: 0.000771, bce: 0.002843, dice: 1.000343\n",
  1609. "val: loss: 0.000595, bce: 0.002020, dice: 1.001034\n",
  1610. "saving best model\n",
  1611. "0m 9s\n",
  1612. "\n",
  1613. "\n",
  1614. "Epoch 34/799\n",
  1615. "----------\n",
  1616. "LR 0.0001\n",
  1617. "train: loss: 0.000587, bce: 0.002280, dice: 1.000454\n",
  1618. "val: loss: 0.000604, bce: 0.002099, dice: 1.001353\n",
  1619. "0m 9s\n",
  1620. "\n",
  1621. "\n",
  1622. "Epoch 35/799\n",
  1623. "----------\n",
  1624. "LR 0.0001\n",
  1625. "train: loss: 0.000527, bce: 0.001867, dice: 1.000518\n",
  1626. "val: loss: 0.000511, bce: 0.001625, dice: 1.001077\n",
  1627. "saving best model\n",
  1628. "0m 9s\n",
  1629. "\n",
  1630. "\n",
  1631. "Epoch 36/799\n",
  1632. "----------\n",
  1633. "LR 0.0001\n",
  1634. "train: loss: 0.000528, bce: 0.001577, dice: 1.000467\n",
  1635. "val: loss: 0.000658, bce: 0.003471, dice: 1.001595\n",
  1636. "0m 9s\n",
  1637. "\n",
  1638. "\n",
  1639. "Epoch 37/799\n",
  1640. "----------\n",
  1641. "LR 0.0001\n",
  1642. "train: loss: 0.000489, bce: 0.001897, dice: 1.000497\n",
  1643. "val: loss: 0.000517, bce: 0.002065, dice: 1.001541\n",
  1644. "0m 9s\n",
  1645. "\n",
  1646. "\n",
  1647. "Epoch 38/799\n",
  1648. "----------\n",
  1649. "LR 0.0001\n",
  1650. "train: loss: 0.000465, bce: 0.001596, dice: 1.000580\n",
  1651. "val: loss: 0.000416, bce: 0.001209, dice: 1.001142\n",
  1652. "saving best model\n",
  1653. "0m 9s\n",
  1654. "\n",
  1655. "\n",
  1656. "Epoch 39/799\n",
  1657. "----------\n",
  1658. "LR 0.0001\n",
  1659. "train: loss: 0.000576, bce: 0.001908, dice: 1.000661\n",
  1660. "val: loss: 0.001376, bce: 0.002086, dice: 1.000165\n",
  1661. "0m 9s\n",
  1662. "\n",
  1663. "\n",
  1664. "Epoch 40/799\n",
  1665. "----------\n",
  1666. "LR 0.0001\n",
  1667. "train: loss: 0.000907, bce: 0.004724, dice: 1.000367\n",
  1668. "val: loss: 0.000680, bce: 0.002080, dice: 1.000715\n",
  1669. "0m 9s\n",
  1670. "\n",
  1671. "\n",
  1672. "Epoch 41/799\n",
  1673. "----------\n",
  1674. "LR 0.0001\n",
  1675. "train: loss: 0.000529, bce: 0.001955, dice: 1.000478\n",
  1676. "val: loss: 0.000451, bce: 0.001721, dice: 1.001276\n",
  1677. "0m 9s\n",
  1678. "\n",
  1679. "\n",
  1680. "Epoch 42/799\n",
  1681. "----------\n",
  1682. "LR 0.0001\n",
  1683. "train: loss: 0.000439, bce: 0.001542, dice: 1.000578\n",
  1684. "val: loss: 0.000430, bce: 0.001809, dice: 1.001767\n",
  1685. "0m 9s\n",
  1686. "\n",
  1687. "\n",
  1688. "Epoch 43/799\n",
  1689. "----------\n",
  1690. "LR 0.0001\n",
  1691. "train: loss: 0.000446, bce: 0.001597, dice: 1.000671\n",
  1692. "val: loss: 0.000397, bce: 0.001215, dice: 1.001177\n",
  1693. "saving best model\n",
  1694. "0m 9s\n",
  1695. "\n",
  1696. "\n",
  1697. "Epoch 44/799\n",
  1698. "----------\n",
  1699. "LR 0.0001\n",
  1700. "train: loss: 0.000439, bce: 0.001341, dice: 1.000588\n",
  1701. "val: loss: 0.000390, bce: 0.001305, dice: 1.001502\n",
  1702. "saving best model\n",
  1703. "0m 9s\n",
  1704. "\n",
  1705. "\n",
  1706. "Epoch 45/799\n",
  1707. "----------\n",
  1708. "LR 0.0001\n",
  1709. "train: loss: 0.000387, bce: 0.001245, dice: 1.000667\n",
  1710. "val: loss: 0.000352, bce: 0.001163, dice: 1.001613\n",
  1711. "saving best model\n",
  1712. "0m 9s\n",
  1713. "\n",
  1714. "\n",
  1715. "Epoch 46/799\n",
  1716. "----------\n",
  1717. "LR 0.0001\n",
  1718. "train: loss: 0.000408, bce: 0.001216, dice: 1.000666\n",
  1719. "val: loss: 0.000518, bce: 0.001493, dice: 1.001949\n",
  1720. "0m 9s\n",
  1721. "\n",
  1722. "\n",
  1723. "Epoch 47/799\n",
  1724. "----------\n",
  1725. "LR 0.0001\n",
  1726. "train: loss: 0.000648, bce: 0.001660, dice: 1.000526\n",
  1727. "val: loss: 0.000429, bce: 0.001987, dice: 1.001340\n",
  1728. "0m 9s\n",
  1729. "\n",
  1730. "\n",
  1731. "Epoch 48/799\n",
  1732. "----------\n",
  1733. "LR 0.0001\n",
  1734. "train: loss: 0.000418, bce: 0.001509, dice: 1.000503\n",
  1735. "val: loss: 0.000408, bce: 0.001389, dice: 1.001599\n",
  1736. "0m 9s\n",
  1737. "\n",
  1738. "\n",
  1739. "Epoch 49/799\n",
  1740. "----------\n",
  1741. "LR 0.0001\n",
  1742. "train: loss: 0.000373, bce: 0.001157, dice: 1.000609\n",
  1743. "val: loss: 0.000346, bce: 0.001087, dice: 1.001590\n",
  1744. "saving best model\n",
  1745. "0m 9s\n",
  1746. "\n",
  1747. "\n",
  1748. "Epoch 50/799\n",
  1749. "----------\n",
  1750. "LR 0.0001\n",
  1751. "train: loss: 0.000341, bce: 0.001027, dice: 1.000651\n",
  1752. "val: loss: 0.000322, bce: 0.000881, dice: 1.001482\n",
  1753. "saving best model\n",
  1754. "0m 9s\n",
  1755. "\n",
  1756. "\n",
  1757. "Epoch 51/799\n",
  1758. "----------\n",
  1759. "LR 0.0001\n",
  1760. "train: loss: 0.000574, bce: 0.001741, dice: 1.000722\n",
  1761. "val: loss: 0.000668, bce: 0.001737, dice: 1.000547\n",
  1762. "0m 9s\n",
  1763. "\n",
  1764. "\n",
  1765. "Epoch 52/799\n",
  1766. "----------\n",
  1767. "LR 0.0001\n",
  1768. "train: loss: 0.000506, bce: 0.001493, dice: 1.000381\n",
  1769. "val: loss: 0.000355, bce: 0.001152, dice: 1.001320\n",
  1770. "0m 9s\n",
  1771. "\n",
  1772. "\n",
  1773. "Epoch 53/799\n",
  1774. "----------\n",
  1775. "LR 0.0001\n",
  1776. "train: loss: 0.000360, bce: 0.001101, dice: 1.000544\n",
  1777. "val: loss: 0.000326, bce: 0.001000, dice: 1.001548\n",
  1778. "0m 9s\n",
  1779. "\n",
  1780. "\n",
  1781. "Epoch 54/799\n",
  1782. "----------\n",
  1783. "LR 0.0001\n",
  1784. "train: loss: 0.000336, bce: 0.000977, dice: 1.000666\n",
  1785. "val: loss: 0.000367, bce: 0.000892, dice: 1.001225\n",
  1786. "0m 9s\n",
  1787. "\n",
  1788. "\n",
  1789. "Epoch 55/799\n",
  1790. "----------\n",
  1791. "LR 0.0001\n",
  1792. "train: loss: 0.000374, bce: 0.001069, dice: 1.000624\n",
  1793. "val: loss: 0.000299, bce: 0.000857, dice: 1.001388\n",
  1794. "saving best model\n",
  1795. "0m 9s\n",
  1796. "\n",
  1797. "\n",
  1798. "Epoch 56/799\n",
  1799. "----------\n",
  1800. "LR 0.0001\n",
  1801. "train: loss: 0.000310, bce: 0.000869, dice: 1.000644\n",
  1802. "val: loss: 0.000320, bce: 0.001038, dice: 1.001939\n",
  1803. "0m 9s\n",
  1804. "\n",
  1805. "\n",
  1806. "Epoch 57/799\n",
  1807. "----------\n",
  1808. "LR 0.0001\n",
  1809. "train: loss: 0.000439, bce: 0.001121, dice: 1.000676\n",
  1810. "val: loss: 0.000546, bce: 0.001779, dice: 1.001407\n",
  1811. "0m 9s\n",
  1812. "\n",
  1813. "\n",
  1814. "Epoch 58/799\n",
  1815. "----------\n",
  1816. "LR 0.0001\n",
  1817. "train: loss: 0.000398, bce: 0.001245, dice: 1.000537\n",
  1818. "val: loss: 0.000317, bce: 0.000879, dice: 1.001133\n",
  1819. "0m 9s\n",
  1820. "\n",
  1821. "\n",
  1822. "Epoch 59/799\n",
  1823. "----------\n",
  1824. "LR 0.0001\n",
  1825. "train: loss: 0.000317, bce: 0.000856, dice: 1.000557\n",
  1826. "val: loss: 0.000296, bce: 0.000804, dice: 1.001133\n",
  1827. "saving best model\n",
  1828. "0m 9s\n",
  1829. "\n",
  1830. "\n",
  1831. "Epoch 60/799\n",
  1832. "----------\n",
  1833. "LR 0.0001\n",
  1834. "train: loss: 0.000324, bce: 0.000890, dice: 1.000627\n",
  1835. "val: loss: 0.000431, bce: 0.000977, dice: 1.000926\n",
  1836. "0m 9s\n",
  1837. "\n",
  1838. "\n",
  1839. "Epoch 61/799\n",
  1840. "----------\n",
  1841. "LR 0.0001\n",
  1842. "train: loss: 0.000324, bce: 0.000856, dice: 1.000553\n",
  1843. "val: loss: 0.000340, bce: 0.000956, dice: 1.001582\n",
  1844. "0m 9s\n",
  1845. "\n",
  1846. "\n",
  1847. "Epoch 62/799\n",
  1848. "----------\n",
  1849. "LR 0.0001\n",
  1850. "train: loss: 0.000343, bce: 0.000900, dice: 1.000615\n",
  1851. "val: loss: 0.000284, bce: 0.000837, dice: 1.001234\n",
  1852. "saving best model\n",
  1853. "0m 9s\n",
  1854. "\n",
  1855. "\n",
  1856. "Epoch 63/799\n",
  1857. "----------\n",
  1858. "LR 0.0001\n",
  1859. "train: loss: 0.000308, bce: 0.000852, dice: 1.000602\n",
  1860. "val: loss: 0.000293, bce: 0.000750, dice: 1.001036\n",
  1861. "0m 9s\n",
  1862. "\n",
  1863. "\n",
  1864. "Epoch 64/799\n",
  1865. "----------\n",
  1866. "LR 0.0001\n",
  1867. "train: loss: 0.000291, bce: 0.000801, dice: 1.000617\n",
  1868. "val: loss: 0.000282, bce: 0.000722, dice: 1.001262\n",
  1869. "saving best model\n",
  1870. "0m 9s\n",
  1871. "\n",
  1872. "\n",
  1873. "Epoch 65/799\n",
  1874. "----------\n",
  1875. "LR 0.0001\n",
  1876. "train: loss: 0.000297, bce: 0.000795, dice: 1.000676\n",
  1877. "val: loss: 0.000537, bce: 0.000966, dice: 1.000828\n",
  1878. "0m 9s\n",
  1879. "\n",
  1880. "\n",
  1881. "Epoch 66/799\n",
  1882. "----------\n",
  1883. "LR 0.0001\n",
  1884. "train: loss: 0.000385, bce: 0.001049, dice: 1.000548\n",
  1885. "val: loss: 0.000283, bce: 0.000791, dice: 1.001137\n",
  1886. "0m 9s\n",
  1887. "\n",
  1888. "\n",
  1889. "Epoch 67/799\n",
  1890. "----------\n",
  1891. "LR 0.0001\n",
  1892. "train: loss: 0.000280, bce: 0.000764, dice: 1.000577\n",
  1893. "val: loss: 0.000273, bce: 0.000718, dice: 1.001149\n",
  1894. "saving best model\n",
  1895. "0m 9s\n",
  1896. "\n",
  1897. "\n",
  1898. "Epoch 68/799\n",
  1899. "----------\n",
  1900. "LR 0.0001\n",
  1901. "train: loss: 0.000314, bce: 0.000837, dice: 1.000677\n",
  1902. "val: loss: 0.000422, bce: 0.000873, dice: 1.000975\n",
  1903. "0m 9s\n",
  1904. "\n",
  1905. "\n",
  1906. "Epoch 69/799\n",
  1907. "----------\n",
  1908. "LR 0.0001\n",
  1909. "train: loss: 0.000307, bce: 0.000825, dice: 1.000602\n",
  1910. "val: loss: 0.000273, bce: 0.000717, dice: 1.001158\n",
  1911. "saving best model\n",
  1912. "0m 9s\n",
  1913. "\n",
  1914. "\n",
  1915. "Epoch 70/799\n",
  1916. "----------\n",
  1917. "LR 0.0001\n",
  1918. "train: loss: 0.000368, bce: 0.000811, dice: 1.000515\n",
  1919. "val: loss: 0.000664, bce: 0.002018, dice: 1.001681\n",
  1920. "0m 9s\n",
  1921. "\n",
  1922. "\n",
  1923. "Epoch 71/799\n",
  1924. "----------\n",
  1925. "LR 0.0001\n",
  1926. "train: loss: 0.033772, bce: 0.049883, dice: 1.000462\n",
  1927. "val: loss: 0.017069, bce: 0.122445, dice: 0.999526\n",
  1928. "0m 9s\n",
  1929. "\n",
  1930. "\n",
  1931. "Epoch 72/799\n",
  1932. "----------\n",
  1933. "LR 0.0001\n",
  1934. "train: loss: 0.010027, bce: 0.037787, dice: 0.999328\n",
  1935. "val: loss: 0.001985, bce: 0.005178, dice: 0.999583\n",
  1936. "0m 9s\n",
  1937. "\n",
  1938. "\n",
  1939. "Epoch 73/799\n",
  1940. "----------\n",
  1941. "LR 0.0001\n",
  1942. "train: loss: 0.001512, bce: 0.006318, dice: 0.999640\n",
  1943. "val: loss: 0.001487, bce: 0.007158, dice: 0.999837\n",
  1944. "0m 9s\n",
  1945. "\n",
  1946. "\n",
  1947. "Epoch 74/799\n",
  1948. "----------\n",
  1949. "LR 0.0001\n",
  1950. "train: loss: 0.001236, bce: 0.006821, dice: 0.999780\n",
  1951. "val: loss: 0.001345, bce: 0.005467, dice: 0.999899\n",
  1952. "0m 9s\n",
  1953. "\n",
  1954. "\n",
  1955. "Epoch 75/799\n",
  1956. "----------\n",
  1957. "LR 0.0001\n",
  1958. "train: loss: 0.001104, bce: 0.005164, dice: 0.999851\n",
  1959. "val: loss: 0.001278, bce: 0.004877, dice: 0.999922\n",
  1960. "0m 9s\n",
  1961. "\n",
  1962. "\n",
  1963. "Epoch 76/799\n",
  1964. "----------\n",
  1965. "LR 0.0001\n",
  1966. "train: loss: 0.000986, bce: 0.004139, dice: 0.999890\n",
  1967. "val: loss: 0.001095, bce: 0.004413, dice: 1.000131\n",
  1968. "0m 9s\n",
  1969. "\n",
  1970. "\n",
  1971. "Epoch 77/799\n",
  1972. "----------\n",
  1973. "LR 0.0001\n",
  1974. "train: loss: 0.000855, bce: 0.003534, dice: 1.000010\n",
  1975. "val: loss: 0.000865, bce: 0.003464, dice: 1.000424\n",
  1976. "0m 9s\n",
  1977. "\n",
  1978. "\n",
  1979. "Epoch 78/799\n",
  1980. "----------\n",
  1981. "LR 0.0001\n",
  1982. "train: loss: 0.000643, bce: 0.002700, dice: 1.000201\n",
  1983. "val: loss: 0.000631, bce: 0.002671, dice: 1.001089\n",
  1984. "0m 9s\n",
  1985. "\n",
  1986. "\n",
  1987. "Epoch 79/799\n",
  1988. "----------\n",
  1989. "LR 0.0001\n",
  1990. "train: loss: 0.000785, bce: 0.002485, dice: 1.000223\n",
  1991. "val: loss: 0.000536, bce: 0.002171, dice: 1.000854\n",
  1992. "0m 9s\n",
  1993. "\n",
  1994. "\n",
  1995. "Epoch 80/799\n",
  1996. "----------\n",
  1997. "LR 0.0001\n",
  1998. "train: loss: 0.000508, bce: 0.002071, dice: 1.000404\n",
  1999. "val: loss: 0.000425, bce: 0.001696, dice: 1.001138\n",
  2000. "0m 9s\n",
  2001. "\n",
  2002. "\n",
  2003. "Epoch 81/799\n",
  2004. "----------\n",
  2005. "LR 0.0001\n",
  2006. "train: loss: 0.000447, bce: 0.001626, dice: 1.000475\n",
  2007. "val: loss: 0.000389, bce: 0.001472, dice: 1.001113\n",
  2008. "0m 9s\n",
  2009. "\n",
  2010. "\n",
  2011. "Epoch 82/799\n",
  2012. "----------\n",
  2013. "LR 0.0001\n",
  2014. "train: loss: 0.000369, bce: 0.001423, dice: 1.000581\n",
  2015. "val: loss: 0.000400, bce: 0.001388, dice: 1.001142\n",
  2016. "0m 9s\n",
  2017. "\n",
  2018. "\n",
  2019. "Epoch 83/799\n",
  2020. "----------\n",
  2021. "LR 0.0001\n",
  2022. "train: loss: 0.000381, bce: 0.001312, dice: 1.000569\n",
  2023. "val: loss: 0.000375, bce: 0.001375, dice: 1.001145\n",
  2024. "0m 9s\n",
  2025. "\n",
  2026. "\n",
  2027. "Epoch 84/799\n",
  2028. "----------\n",
  2029. "LR 0.0001\n",
  2030. "train: loss: 0.000381, bce: 0.001265, dice: 1.000569\n",
  2031. "val: loss: 0.000399, bce: 0.001553, dice: 1.001426\n",
  2032. "0m 9s\n",
  2033. "\n",
  2034. "\n",
  2035. "Epoch 85/799\n",
  2036. "----------\n",
  2037. "LR 0.0001\n",
  2038. "train: loss: 0.000370, bce: 0.001397, dice: 1.000549\n",
  2039. "val: loss: 0.000334, bce: 0.001226, dice: 1.001439\n",
  2040. "0m 9s\n",
  2041. "\n",
  2042. "\n",
  2043. "Epoch 86/799\n",
  2044. "----------\n",
  2045. "LR 0.0001\n",
  2046. "train: loss: 0.000436, bce: 0.001293, dice: 1.000544\n",
  2047. "val: loss: 0.000378, bce: 0.001447, dice: 1.001050\n",
  2048. "0m 9s\n",
  2049. "\n",
  2050. "\n",
  2051. "Epoch 87/799\n",
  2052. "----------\n",
  2053. "LR 0.0001\n",
  2054. "train: loss: 0.000371, bce: 0.001411, dice: 1.000525\n",
  2055. "val: loss: 0.000315, bce: 0.001131, dice: 1.001383\n",
  2056. "0m 9s\n",
  2057. "\n",
  2058. "\n",
  2059. "Epoch 88/799\n",
  2060. "----------\n",
  2061. "LR 0.0001\n",
  2062. "train: loss: 0.000308, bce: 0.001141, dice: 1.000675\n",
  2063. "val: loss: 0.000341, bce: 0.001018, dice: 1.001276\n",
  2064. "0m 9s\n",
  2065. "\n",
  2066. "\n",
  2067. "Epoch 89/799\n",
  2068. "----------\n",
  2069. "LR 0.0001\n",
  2070. "train: loss: 0.000302, bce: 0.001032, dice: 1.000685\n",
  2071. "val: loss: 0.000338, bce: 0.000975, dice: 1.001313\n",
  2072. "0m 9s\n",
  2073. "\n",
  2074. "\n",
  2075. "Epoch 90/799\n",
  2076. "----------\n",
  2077. "LR 0.0001\n",
  2078. "train: loss: 0.000347, bce: 0.001088, dice: 1.000704\n",
  2079. "val: loss: 0.000802, bce: 0.001505, dice: 1.000498\n",
  2080. "0m 9s\n",
  2081. "\n",
  2082. "\n",
  2083. "Epoch 91/799\n",
  2084. "----------\n",
  2085. "LR 0.0001\n",
  2086. "train: loss: 0.000458, bce: 0.001414, dice: 1.000374\n",
  2087. "val: loss: 0.000368, bce: 0.001247, dice: 1.001114\n",
  2088. "0m 9s\n",
  2089. "\n",
  2090. "\n",
  2091. "Epoch 92/799\n",
  2092. "----------\n",
  2093. "LR 0.0001\n",
  2094. "train: loss: 0.000311, bce: 0.001099, dice: 1.000558\n",
  2095. "val: loss: 0.000316, bce: 0.001000, dice: 1.001191\n",
  2096. "0m 9s\n",
  2097. "\n",
  2098. "\n",
  2099. "Epoch 93/799\n",
  2100. "----------\n",
  2101. "LR 0.0001\n",
  2102. "train: loss: 0.000318, bce: 0.000970, dice: 1.000618\n",
  2103. "val: loss: 0.000320, bce: 0.001185, dice: 1.001449\n",
  2104. "0m 9s\n",
  2105. "\n",
  2106. "\n",
  2107. "Epoch 94/799\n",
  2108. "----------\n",
  2109. "LR 0.0001\n",
  2110. "train: loss: 0.000295, bce: 0.001025, dice: 1.000621\n",
  2111. "val: loss: 0.000294, bce: 0.000944, dice: 1.001395\n",
  2112. "0m 9s\n",
  2113. "\n",
  2114. "\n",
  2115. "Epoch 95/799\n",
  2116. "----------\n",
  2117. "LR 0.0001\n",
  2118. "train: loss: 0.000285, bce: 0.000886, dice: 1.000632\n",
  2119. "val: loss: 0.000293, bce: 0.000944, dice: 1.001373\n",
  2120. "0m 9s\n",
  2121. "\n",
  2122. "\n",
  2123. "Epoch 96/799\n",
  2124. "----------\n",
  2125. "LR 0.0001\n",
  2126. "train: loss: 0.000270, bce: 0.000862, dice: 1.000640\n",
  2127. "val: loss: 0.000280, bce: 0.000818, dice: 1.001340\n",
  2128. "0m 9s\n",
  2129. "\n",
  2130. "\n",
  2131. "Epoch 97/799\n",
  2132. "----------\n",
  2133. "LR 0.0001\n",
  2134. "train: loss: 0.000277, bce: 0.000838, dice: 1.000673\n",
  2135. "val: loss: 0.000342, bce: 0.000878, dice: 1.001103\n",
  2136. "0m 9s\n",
  2137. "\n",
  2138. "\n",
  2139. "Epoch 98/799\n",
  2140. "----------\n",
  2141. "LR 0.0001\n",
  2142. "train: loss: 0.000314, bce: 0.000939, dice: 1.000563\n",
  2143. "val: loss: 0.000285, bce: 0.000881, dice: 1.001432\n",
  2144. "0m 9s\n",
  2145. "\n",
  2146. "\n",
  2147. "Epoch 99/799\n",
  2148. "----------\n",
  2149. "LR 0.0001\n",
  2150. "train: loss: 0.000259, bce: 0.000811, dice: 1.000654\n",
  2151. "val: loss: 0.000267, bce: 0.000766, dice: 1.001436\n",
  2152. "saving best model\n",
  2153. "0m 9s\n",
  2154. "\n",
  2155. "\n",
  2156. "Epoch 100/799\n",
  2157. "----------\n",
  2158. "LR 0.0001\n",
  2159. "train: loss: 0.000257, bce: 0.000747, dice: 1.000672\n",
  2160. "val: loss: 0.000264, bce: 0.000762, dice: 1.001480\n",
  2161. "saving best model\n",
  2162. "0m 9s\n",
  2163. "\n",
  2164. "\n",
  2165. "Epoch 101/799\n",
  2166. "----------\n",
  2167. "LR 0.0001\n",
  2168. "train: loss: 0.000372, bce: 0.000958, dice: 1.000754\n",
  2169. "val: loss: 0.000514, bce: 0.001214, dice: 1.000714\n",
  2170. "0m 9s\n",
  2171. "\n",
  2172. "\n",
  2173. "Epoch 102/799\n",
  2174. "----------\n",
  2175. "LR 0.0001\n",
  2176. "train: loss: 0.000346, bce: 0.001010, dice: 1.000464\n",
  2177. "val: loss: 0.000280, bce: 0.000941, dice: 1.001263\n",
  2178. "0m 9s\n",
  2179. "\n",
  2180. "\n",
  2181. "Epoch 103/799\n",
  2182. "----------\n",
  2183. "LR 0.0001\n",
  2184. "train: loss: 0.000262, bce: 0.000852, dice: 1.000599\n",
  2185. "val: loss: 0.000267, bce: 0.000811, dice: 1.001249\n",
  2186. "0m 9s\n",
  2187. "\n",
  2188. "\n",
  2189. "Epoch 104/799\n",
  2190. "----------\n",
  2191. "LR 0.0001\n",
  2192. "train: loss: 0.000253, bce: 0.000776, dice: 1.000606\n",
  2193. "val: loss: 0.000263, bce: 0.000762, dice: 1.001295\n",
  2194. "saving best model\n",
  2195. "0m 9s\n",
  2196. "\n",
  2197. "\n",
  2198. "Epoch 105/799\n",
  2199. "----------\n",
  2200. "LR 0.0001\n",
  2201. "train: loss: 0.000252, bce: 0.000726, dice: 1.000654\n",
  2202. "val: loss: 0.000303, bce: 0.000768, dice: 1.001104\n",
  2203. "0m 9s\n",
  2204. "\n",
  2205. "\n",
  2206. "Epoch 106/799\n",
  2207. "----------\n",
  2208. "LR 0.0001\n",
  2209. "train: loss: 0.000327, bce: 0.000895, dice: 1.000588\n",
  2210. "val: loss: 0.000270, bce: 0.000834, dice: 1.001199\n",
  2211. "0m 9s\n",
  2212. "\n",
  2213. "\n",
  2214. "Epoch 107/799\n",
  2215. "----------\n",
  2216. "LR 0.0001\n",
  2217. "train: loss: 0.000251, bce: 0.000777, dice: 1.000604\n",
  2218. "val: loss: 0.000256, bce: 0.000760, dice: 1.001392\n",
  2219. "saving best model\n",
  2220. "0m 9s\n",
  2221. "\n",
  2222. "\n",
  2223. "Epoch 108/799\n",
  2224. "----------\n",
  2225. "LR 0.0001\n",
  2226. "train: loss: 0.000247, bce: 0.000718, dice: 1.000652\n",
  2227. "val: loss: 0.000304, bce: 0.000740, dice: 1.001152\n",
  2228. "0m 9s\n",
  2229. "\n",
  2230. "\n",
  2231. "Epoch 109/799\n",
  2232. "----------\n",
  2233. "LR 0.0001\n",
  2234. "train: loss: 0.000280, bce: 0.000759, dice: 1.000594\n",
  2235. "val: loss: 0.000269, bce: 0.000802, dice: 1.001468\n",
  2236. "0m 9s\n",
  2237. "\n",
  2238. "\n",
  2239. "Epoch 110/799\n",
  2240. "----------\n",
  2241. "LR 0.0001\n",
  2242. "train: loss: 0.000246, bce: 0.000725, dice: 1.000636\n",
  2243. "val: loss: 0.000292, bce: 0.000800, dice: 1.001556\n",
  2244. "0m 9s\n",
  2245. "\n",
  2246. "\n",
  2247. "Epoch 111/799\n",
  2248. "----------\n",
  2249. "LR 0.0001\n",
  2250. "train: loss: 0.000268, bce: 0.000722, dice: 1.000664\n",
  2251. "val: loss: 0.000275, bce: 0.000805, dice: 1.001572\n",
  2252. "0m 9s\n",
  2253. "\n",
  2254. "\n",
  2255. "Epoch 112/799\n",
  2256. "----------\n",
  2257. "LR 0.0001\n",
  2258. "train: loss: 0.000287, bce: 0.000811, dice: 1.000626\n",
  2259. "val: loss: 0.000254, bce: 0.000753, dice: 1.001320\n",
  2260. "saving best model\n",
  2261. "0m 9s\n",
  2262. "\n",
  2263. "\n",
  2264. "Epoch 113/799\n",
  2265. "----------\n",
  2266. "LR 0.0001\n",
  2267. "train: loss: 0.000243, bce: 0.000707, dice: 1.000625\n",
  2268. "val: loss: 0.000249, bce: 0.000693, dice: 1.001347\n",
  2269. "saving best model\n",
  2270. "0m 9s\n",
  2271. "\n",
  2272. "\n",
  2273. "Epoch 114/799\n",
  2274. "----------\n",
  2275. "LR 0.0001\n",
  2276. "train: loss: 0.000235, bce: 0.000657, dice: 1.000648\n",
  2277. "val: loss: 0.000249, bce: 0.000684, dice: 1.001380\n",
  2278. "0m 9s\n",
  2279. "\n",
  2280. "\n",
  2281. "Epoch 115/799\n",
  2282. "----------\n",
  2283. "LR 0.0001\n",
  2284. "train: loss: 0.000320, bce: 0.000822, dice: 1.000680\n",
  2285. "val: loss: 0.000351, bce: 0.001033, dice: 1.001007\n",
  2286. "0m 9s\n",
  2287. "\n",
  2288. "\n",
  2289. "Epoch 116/799\n",
  2290. "----------\n",
  2291. "LR 0.0001\n",
  2292. "train: loss: 0.000296, bce: 0.000842, dice: 1.000531\n",
  2293. "val: loss: 0.000287, bce: 0.000807, dice: 1.001493\n",
  2294. "0m 9s\n",
  2295. "\n",
  2296. "\n",
  2297. "Epoch 117/799\n",
  2298. "----------\n",
  2299. "LR 0.0001\n",
  2300. "train: loss: 0.000279, bce: 0.000771, dice: 1.000600\n",
  2301. "val: loss: 0.000307, bce: 0.000871, dice: 1.001589\n",
  2302. "0m 9s\n",
  2303. "\n",
  2304. "\n",
  2305. "Epoch 118/799\n",
  2306. "----------\n",
  2307. "LR 0.0001\n",
  2308. "train: loss: 0.000276, bce: 0.000788, dice: 1.000610\n",
  2309. "val: loss: 0.000261, bce: 0.000725, dice: 1.001143\n",
  2310. "0m 9s\n",
  2311. "\n",
  2312. "\n",
  2313. "Epoch 119/799\n",
  2314. "----------\n",
  2315. "LR 0.0001\n",
  2316. "train: loss: 0.000244, bce: 0.000688, dice: 1.000626\n",
  2317. "val: loss: 0.000253, bce: 0.000700, dice: 1.001237\n",
  2318. "0m 9s\n",
  2319. "\n",
  2320. "\n",
  2321. "Epoch 120/799\n",
  2322. "----------\n",
  2323. "LR 0.0001\n",
  2324. "train: loss: 0.000235, bce: 0.000653, dice: 1.000624\n",
  2325. "val: loss: 0.000238, bce: 0.000659, dice: 1.001331\n",
  2326. "saving best model\n",
  2327. "0m 9s\n",
  2328. "\n",
  2329. "\n",
  2330. "Epoch 121/799\n",
  2331. "----------\n",
  2332. "LR 0.0001\n",
  2333. "train: loss: 0.000264, bce: 0.000705, dice: 1.000645\n",
  2334. "val: loss: 0.000264, bce: 0.000738, dice: 1.001329\n",
  2335. "0m 9s\n",
  2336. "\n",
  2337. "\n",
  2338. "Epoch 122/799\n",
  2339. "----------\n",
  2340. "LR 0.0001\n",
  2341. "train: loss: 0.000256, bce: 0.000683, dice: 1.000646\n",
  2342. "val: loss: 0.000326, bce: 0.000761, dice: 1.001018\n",
  2343. "0m 9s\n",
  2344. "\n",
  2345. "\n",
  2346. "Epoch 123/799\n",
  2347. "----------\n",
  2348. "LR 0.0001\n",
  2349. "train: loss: 0.000241, bce: 0.000667, dice: 1.000592\n",
  2350. "val: loss: 0.000247, bce: 0.000712, dice: 1.001460\n",
  2351. "0m 9s\n",
  2352. "\n",
  2353. "\n",
  2354. "Epoch 124/799\n",
  2355. "----------\n",
  2356. "LR 0.0001\n",
  2357. "train: loss: 0.000244, bce: 0.000671, dice: 1.000634\n",
  2358. "val: loss: 0.000235, bce: 0.000650, dice: 1.001379\n",
  2359. "saving best model\n",
  2360. "0m 9s\n",
  2361. "\n",
  2362. "\n",
  2363. "Epoch 125/799\n",
  2364. "----------\n",
  2365. "LR 0.0001\n",
  2366. "train: loss: 0.000225, bce: 0.000607, dice: 1.000648\n",
  2367. "val: loss: 0.000254, bce: 0.000681, dice: 1.001439\n",
  2368. "0m 9s\n",
  2369. "\n",
  2370. "\n",
  2371. "Epoch 126/799\n",
  2372. "----------\n",
  2373. "LR 0.0001\n",
  2374. "train: loss: 0.000222, bce: 0.000601, dice: 1.000672\n",
  2375. "val: loss: 0.000234, bce: 0.000625, dice: 1.001264\n",
  2376. "saving best model\n",
  2377. "0m 9s\n",
  2378. "\n",
  2379. "\n",
  2380. "Epoch 127/799\n",
  2381. "----------\n",
  2382. "LR 0.0001\n",
  2383. "train: loss: 0.000299, bce: 0.000698, dice: 1.000731\n",
  2384. "val: loss: 0.000596, bce: 0.001134, dice: 1.000574\n",
  2385. "0m 9s\n",
  2386. "\n",
  2387. "\n",
  2388. "Epoch 128/799\n",
  2389. "----------\n",
  2390. "LR 0.0001\n",
  2391. "train: loss: 0.000345, bce: 0.000936, dice: 1.000453\n",
  2392. "val: loss: 0.000249, bce: 0.000769, dice: 1.001193\n",
  2393. "0m 9s\n",
  2394. "\n",
  2395. "\n",
  2396. "Epoch 129/799\n",
  2397. "----------\n",
  2398. "LR 0.0001\n",
  2399. "train: loss: 0.000232, bce: 0.000684, dice: 1.000603\n",
  2400. "val: loss: 0.000239, bce: 0.000675, dice: 1.001264\n",
  2401. "0m 9s\n",
  2402. "\n",
  2403. "\n",
  2404. "Epoch 130/799\n",
  2405. "----------\n",
  2406. "LR 0.0001\n",
  2407. "train: loss: 0.000231, bce: 0.000645, dice: 1.000636\n",
  2408. "val: loss: 0.000238, bce: 0.000652, dice: 1.001281\n",
  2409. "0m 9s\n",
  2410. "\n",
  2411. "\n",
  2412. "Epoch 131/799\n",
  2413. "----------\n",
  2414. "LR 0.0001\n",
  2415. "train: loss: 0.000239, bce: 0.000630, dice: 1.000615\n",
  2416. "val: loss: 0.000243, bce: 0.000639, dice: 1.001249\n",
  2417. "0m 9s\n",
  2418. "\n",
  2419. "\n",
  2420. "Epoch 132/799\n",
  2421. "----------\n",
  2422. "LR 0.0001\n",
  2423. "train: loss: 0.000227, bce: 0.000614, dice: 1.000638\n",
  2424. "val: loss: 0.000230, bce: 0.000623, dice: 1.001338\n",
  2425. "saving best model\n",
  2426. "0m 9s\n",
  2427. "\n",
  2428. "\n",
  2429. "Epoch 133/799\n",
  2430. "----------\n",
  2431. "LR 0.0001\n",
  2432. "train: loss: 0.000257, bce: 0.000670, dice: 1.000651\n",
  2433. "val: loss: 0.000275, bce: 0.000690, dice: 1.001121\n",
  2434. "0m 9s\n",
  2435. "\n",
  2436. "\n",
  2437. "Epoch 134/799\n",
  2438. "----------\n",
  2439. "LR 0.0001\n",
  2440. "train: loss: 0.000242, bce: 0.000643, dice: 1.000638\n",
  2441. "val: loss: 0.000242, bce: 0.000640, dice: 1.001224\n",
  2442. "0m 9s\n",
  2443. "\n",
  2444. "\n",
  2445. "Epoch 135/799\n",
  2446. "----------\n",
  2447. "LR 0.0001\n",
  2448. "train: loss: 0.000233, bce: 0.000617, dice: 1.000664\n",
  2449. "val: loss: 0.000280, bce: 0.000687, dice: 1.001158\n",
  2450. "0m 9s\n",
  2451. "\n",
  2452. "\n",
  2453. "Epoch 136/799\n",
  2454. "----------\n",
  2455. "LR 0.0001\n",
  2456. "train: loss: 0.000237, bce: 0.000631, dice: 1.000650\n",
  2457. "val: loss: 0.000249, bce: 0.000634, dice: 1.001240\n",
  2458. "0m 9s\n",
  2459. "\n",
  2460. "\n",
  2461. "Epoch 137/799\n",
  2462. "----------\n",
  2463. "LR 0.0001\n",
  2464. "train: loss: 0.000252, bce: 0.000646, dice: 1.000678\n",
  2465. "val: loss: 0.000375, bce: 0.000784, dice: 1.001017\n",
  2466. "0m 9s\n",
  2467. "\n",
  2468. "\n",
  2469. "Epoch 138/799\n",
  2470. "----------\n",
  2471. "LR 0.0001\n",
  2472. "train: loss: 0.000269, bce: 0.000670, dice: 1.000577\n",
  2473. "val: loss: 0.000232, bce: 0.000668, dice: 1.001277\n",
  2474. "0m 9s\n",
  2475. "\n",
  2476. "\n",
  2477. "Epoch 139/799\n",
  2478. "----------\n",
  2479. "LR 0.0001\n",
  2480. "train: loss: 0.000227, bce: 0.000615, dice: 1.000611\n",
  2481. "val: loss: 0.000245, bce: 0.000679, dice: 1.001429\n",
  2482. "0m 9s\n",
  2483. "\n",
  2484. "\n",
  2485. "Epoch 140/799\n",
  2486. "----------\n",
  2487. "LR 0.0001\n",
  2488. "train: loss: 0.000213, bce: 0.000580, dice: 1.000642\n",
  2489. "val: loss: 0.000230, bce: 0.000607, dice: 1.001260\n",
  2490. "0m 9s\n",
  2491. "\n",
  2492. "\n",
  2493. "Epoch 141/799\n",
  2494. "----------\n",
  2495. "LR 0.0001\n",
  2496. "train: loss: 0.000218, bce: 0.000569, dice: 1.000637\n",
  2497. "val: loss: 0.000224, bce: 0.000593, dice: 1.001377\n",
  2498. "saving best model\n",
  2499. "0m 9s\n",
  2500. "\n",
  2501. "\n",
  2502. "Epoch 142/799\n",
  2503. "----------\n",
  2504. "LR 0.0001\n",
  2505. "train: loss: 0.000311, bce: 0.000669, dice: 1.000633\n",
  2506. "val: loss: 0.000481, bce: 0.001431, dice: 1.001560\n",
  2507. "0m 9s\n",
  2508. "\n",
  2509. "\n",
  2510. "Epoch 143/799\n",
  2511. "----------\n",
  2512. "LR 0.0001\n",
  2513. "train: loss: 0.000308, bce: 0.000905, dice: 1.000594\n",
  2514. "val: loss: 0.000248, bce: 0.000718, dice: 1.001306\n",
  2515. "0m 9s\n",
  2516. "\n",
  2517. "\n",
  2518. "Epoch 144/799\n",
  2519. "----------\n",
  2520. "LR 0.0001\n",
  2521. "train: loss: 0.000238, bce: 0.000667, dice: 1.000573\n",
  2522. "val: loss: 0.000230, bce: 0.000656, dice: 1.001214\n",
  2523. "0m 9s\n",
  2524. "\n",
  2525. "\n",
  2526. "Epoch 145/799\n",
  2527. "----------\n",
  2528. "LR 0.0001\n",
  2529. "train: loss: 0.000216, bce: 0.000588, dice: 1.000616\n",
  2530. "val: loss: 0.000227, bce: 0.000615, dice: 1.001211\n",
  2531. "0m 9s\n",
  2532. "\n",
  2533. "\n",
  2534. "Epoch 146/799\n",
  2535. "----------\n",
  2536. "LR 0.0001\n",
  2537. "train: loss: 0.000221, bce: 0.000579, dice: 1.000631\n",
  2538. "val: loss: 0.000243, bce: 0.000615, dice: 1.001194\n",
  2539. "0m 9s\n",
  2540. "\n",
  2541. "\n",
  2542. "Epoch 147/799\n",
  2543. "----------\n",
  2544. "LR 0.0001\n",
  2545. "train: loss: 0.000275, bce: 0.000681, dice: 1.000600\n",
  2546. "val: loss: 0.000233, bce: 0.000689, dice: 1.001242\n",
  2547. "0m 9s\n",
  2548. "\n",
  2549. "\n",
  2550. "Epoch 148/799\n",
  2551. "----------\n",
  2552. "LR 0.0001\n",
  2553. "train: loss: 0.000222, bce: 0.000608, dice: 1.000611\n",
  2554. "val: loss: 0.000246, bce: 0.000655, dice: 1.001444\n",
  2555. "0m 9s\n",
  2556. "\n",
  2557. "\n",
  2558. "Epoch 149/799\n",
  2559. "----------\n",
  2560. "LR 0.0001\n",
  2561. "train: loss: 0.000232, bce: 0.000604, dice: 1.000615\n",
  2562. "val: loss: 0.000252, bce: 0.000667, dice: 1.001491\n",
  2563. "0m 9s\n",
  2564. "\n",
  2565. "\n",
  2566. "Epoch 150/799\n",
  2567. "----------\n",
  2568. "LR 0.0001\n",
  2569. "train: loss: 0.000251, bce: 0.000615, dice: 1.000647\n",
  2570. "val: loss: 0.000291, bce: 0.000861, dice: 1.001300\n",
  2571. "0m 9s\n",
  2572. "\n",
  2573. "\n",
  2574. "Epoch 151/799\n",
  2575. "----------\n",
  2576. "LR 0.0001\n",
  2577. "train: loss: 0.000229, bce: 0.000641, dice: 1.000622\n",
  2578. "val: loss: 0.000243, bce: 0.000647, dice: 1.001438\n",
  2579. "0m 9s\n",
  2580. "\n",
  2581. "\n",
  2582. "Epoch 152/799\n",
  2583. "----------\n",
  2584. "LR 0.0001\n",
  2585. "train: loss: 0.000364, bce: 0.000735, dice: 1.000618\n",
  2586. "val: loss: 0.001550, bce: 0.004515, dice: 1.001126\n",
  2587. "0m 9s\n",
  2588. "\n",
  2589. "\n",
  2590. "Epoch 153/799\n",
  2591. "----------\n",
  2592. "LR 0.0001\n",
  2593. "train: loss: 0.001597, bce: 0.003301, dice: 1.000279\n",
  2594. "val: loss: 0.000415, bce: 0.001498, dice: 1.001247\n",
  2595. "0m 9s\n",
  2596. "\n",
  2597. "\n",
  2598. "Epoch 154/799\n",
  2599. "----------\n",
  2600. "LR 0.0001\n",
  2601. "train: loss: 0.000395, bce: 0.001314, dice: 1.000574\n",
  2602. "val: loss: 0.000380, bce: 0.001524, dice: 1.001530\n",
  2603. "0m 9s\n",
  2604. "\n",
  2605. "\n",
  2606. "Epoch 155/799\n",
  2607. "----------\n",
  2608. "LR 0.0001\n",
  2609. "train: loss: 0.000297, bce: 0.001192, dice: 1.000729\n",
  2610. "val: loss: 0.000260, bce: 0.000844, dice: 1.001467\n",
  2611. "0m 9s\n",
  2612. "\n",
  2613. "\n",
  2614. "Epoch 156/799\n",
  2615. "----------\n",
  2616. "LR 0.0001\n",
  2617. "train: loss: 0.000272, bce: 0.000842, dice: 1.000804\n",
  2618. "val: loss: 0.000325, bce: 0.001081, dice: 1.001090\n",
  2619. "0m 9s\n",
  2620. "\n",
  2621. "\n",
  2622. "Epoch 157/799\n",
  2623. "----------\n",
  2624. "LR 0.0001\n",
  2625. "train: loss: 0.000261, bce: 0.000863, dice: 1.000676\n",
  2626. "val: loss: 0.000242, bce: 0.000726, dice: 1.001563\n",
  2627. "0m 9s\n",
  2628. "\n",
  2629. "\n",
  2630. "Epoch 158/799\n",
  2631. "----------\n",
  2632. "LR 0.0001\n",
  2633. "train: loss: 0.000231, bce: 0.000702, dice: 1.000798\n",
  2634. "val: loss: 0.000238, bce: 0.000673, dice: 1.001525\n",
  2635. "0m 9s\n",
  2636. "\n",
  2637. "\n",
  2638. "Epoch 159/799\n",
  2639. "----------\n",
  2640. "LR 0.0001\n",
  2641. "train: loss: 0.000251, bce: 0.000710, dice: 1.000873\n",
  2642. "val: loss: 0.000376, bce: 0.000807, dice: 1.001182\n",
  2643. "0m 9s\n",
  2644. "\n",
  2645. "\n",
  2646. "Epoch 160/799\n",
  2647. "----------\n",
  2648. "LR 0.0001\n",
  2649. "train: loss: 0.000277, bce: 0.000795, dice: 1.000713\n",
  2650. "val: loss: 0.000255, bce: 0.000701, dice: 1.001270\n",
  2651. "0m 9s\n",
  2652. "\n",
  2653. "\n",
  2654. "Epoch 161/799\n",
  2655. "----------\n",
  2656. "LR 0.0001\n",
  2657. "train: loss: 0.000227, bce: 0.000662, dice: 1.000718\n",
  2658. "val: loss: 0.000224, bce: 0.000634, dice: 1.001477\n",
  2659. "0m 9s\n",
  2660. "\n",
  2661. "\n",
  2662. "Epoch 162/799\n",
  2663. "----------\n",
  2664. "LR 0.0001\n",
  2665. "train: loss: 0.000225, bce: 0.000621, dice: 1.000762\n",
  2666. "val: loss: 0.000231, bce: 0.000635, dice: 1.001486\n",
  2667. "0m 9s\n",
  2668. "\n",
  2669. "\n",
  2670. "Epoch 163/799\n",
  2671. "----------\n",
  2672. "LR 0.0001\n",
  2673. "train: loss: 0.000216, bce: 0.000611, dice: 1.000770\n",
  2674. "val: loss: 0.000217, bce: 0.000605, dice: 1.001560\n",
  2675. "saving best model\n",
  2676. "0m 9s\n",
  2677. "\n",
  2678. "\n",
  2679. "Epoch 164/799\n",
  2680. "----------\n",
  2681. "LR 0.0001\n",
  2682. "train: loss: 0.000212, bce: 0.000579, dice: 1.000769\n",
  2683. "val: loss: 0.000310, bce: 0.000670, dice: 1.001168\n",
  2684. "0m 9s\n",
  2685. "\n",
  2686. "\n",
  2687. "Epoch 165/799\n",
  2688. "----------\n",
  2689. "LR 0.0001\n",
  2690. "train: loss: 0.000255, bce: 0.000680, dice: 1.000733\n",
  2691. "val: loss: 0.000254, bce: 0.000666, dice: 1.001306\n",
  2692. "0m 9s\n",
  2693. "\n",
  2694. "\n",
  2695. "Epoch 166/799\n",
  2696. "----------\n",
  2697. "LR 0.0001\n",
  2698. "train: loss: 0.000232, bce: 0.000643, dice: 1.000704\n",
  2699. "val: loss: 0.000217, bce: 0.000614, dice: 1.001430\n",
  2700. "saving best model\n",
  2701. "0m 9s\n",
  2702. "\n",
  2703. "\n",
  2704. "Epoch 167/799\n",
  2705. "----------\n",
  2706. "LR 0.0001\n",
  2707. "train: loss: 0.000232, bce: 0.000616, dice: 1.000731\n",
  2708. "val: loss: 0.000251, bce: 0.000628, dice: 1.001272\n",
  2709. "0m 9s\n",
  2710. "\n",
  2711. "\n",
  2712. "Epoch 168/799\n",
  2713. "----------\n",
  2714. "LR 0.0001\n",
  2715. "train: loss: 0.000230, bce: 0.000609, dice: 1.000695\n",
  2716. "val: loss: 0.000227, bce: 0.000621, dice: 1.001337\n",
  2717. "0m 9s\n",
  2718. "\n",
  2719. "\n",
  2720. "Epoch 169/799\n",
  2721. "----------\n",
  2722. "LR 0.0001\n",
  2723. "train: loss: 0.000216, bce: 0.000588, dice: 1.000725\n",
  2724. "val: loss: 0.000259, bce: 0.000629, dice: 1.001188\n",
  2725. "0m 9s\n",
  2726. "\n",
  2727. "\n",
  2728. "Epoch 170/799\n",
  2729. "----------\n",
  2730. "LR 0.0001\n",
  2731. "train: loss: 0.000244, bce: 0.000638, dice: 1.000718\n",
  2732. "val: loss: 0.000267, bce: 0.000632, dice: 1.001240\n",
  2733. "0m 9s\n",
  2734. "\n",
  2735. "\n",
  2736. "Epoch 171/799\n",
  2737. "----------\n",
  2738. "LR 0.0001\n",
  2739. "train: loss: 0.000212, bce: 0.000563, dice: 1.000737\n",
  2740. "val: loss: 0.000224, bce: 0.000600, dice: 1.001555\n",
  2741. "0m 9s\n",
  2742. "\n",
  2743. "\n",
  2744. "Epoch 172/799\n",
  2745. "----------\n",
  2746. "LR 0.0001\n",
  2747. "train: loss: 0.000213, bce: 0.000545, dice: 1.000733\n",
  2748. "val: loss: 0.000229, bce: 0.000612, dice: 1.001652\n",
  2749. "0m 9s\n",
  2750. "\n",
  2751. "\n",
  2752. "Epoch 173/799\n",
  2753. "----------\n",
  2754. "LR 0.0001\n",
  2755. "train: loss: 0.000272, bce: 0.000634, dice: 1.000674\n",
  2756. "val: loss: 0.000547, bce: 0.001286, dice: 1.001958\n",
  2757. "0m 9s\n",
  2758. "\n",
  2759. "\n",
  2760. "Epoch 174/799\n",
  2761. "----------\n",
  2762. "LR 0.0001\n",
  2763. "train: loss: 0.000264, bce: 0.000770, dice: 1.000702\n",
  2764. "val: loss: 0.000235, bce: 0.000644, dice: 1.001200\n",
  2765. "0m 9s\n",
  2766. "\n",
  2767. "\n",
  2768. "Epoch 175/799\n",
  2769. "----------\n",
  2770. "LR 0.0001\n",
  2771. "train: loss: 0.000210, bce: 0.000574, dice: 1.000665\n",
  2772. "val: loss: 0.000210, bce: 0.000576, dice: 1.001395\n",
  2773. "saving best model\n",
  2774. "0m 9s\n",
  2775. "\n",
  2776. "\n",
  2777. "Epoch 176/799\n",
  2778. "----------\n",
  2779. "LR 0.0001\n",
  2780. "train: loss: 0.000209, bce: 0.000540, dice: 1.000662\n",
  2781. "val: loss: 0.000274, bce: 0.000684, dice: 1.001669\n",
  2782. "0m 9s\n",
  2783. "\n",
  2784. "\n",
  2785. "Epoch 177/799\n",
  2786. "----------\n",
  2787. "LR 0.0001\n",
  2788. "train: loss: 0.000235, bce: 0.000622, dice: 1.000677\n",
  2789. "val: loss: 0.000224, bce: 0.000605, dice: 1.001495\n",
  2790. "0m 9s\n",
  2791. "\n",
  2792. "\n",
  2793. "Epoch 178/799\n",
  2794. "----------\n",
  2795. "LR 0.0001\n",
  2796. "train: loss: 0.000216, bce: 0.000547, dice: 1.000688\n",
  2797. "val: loss: 0.000257, bce: 0.000670, dice: 1.001487\n",
  2798. "0m 9s\n",
  2799. "\n",
  2800. "\n",
  2801. "Epoch 179/799\n",
  2802. "----------\n",
  2803. "LR 0.0001\n",
  2804. "train: loss: 0.000204, bce: 0.000540, dice: 1.000668\n",
  2805. "val: loss: 0.000214, bce: 0.000557, dice: 1.001532\n",
  2806. "0m 9s\n",
  2807. "\n",
  2808. "\n",
  2809. "Epoch 180/799\n",
  2810. "----------\n",
  2811. "LR 0.0001\n",
  2812. "train: loss: 0.000199, bce: 0.000504, dice: 1.000701\n",
  2813. "val: loss: 0.000291, bce: 0.000661, dice: 1.001795\n",
  2814. "0m 9s\n",
  2815. "\n",
  2816. "\n",
  2817. "Epoch 181/799\n",
  2818. "----------\n",
  2819. "LR 0.0001\n",
  2820. "train: loss: 0.000309, bce: 0.000711, dice: 1.000665\n",
  2821. "val: loss: 0.000309, bce: 0.000896, dice: 1.001442\n",
  2822. "0m 9s\n",
  2823. "\n",
  2824. "\n",
  2825. "Epoch 182/799\n",
  2826. "----------\n",
  2827. "LR 0.0001\n",
  2828. "train: loss: 0.000231, bce: 0.000649, dice: 1.000656\n",
  2829. "val: loss: 0.000258, bce: 0.000632, dice: 1.001112\n",
  2830. "0m 9s\n",
  2831. "\n",
  2832. "\n",
  2833. "Epoch 183/799\n",
  2834. "----------\n",
  2835. "LR 0.0001\n",
  2836. "train: loss: 0.000239, bce: 0.000605, dice: 1.000608\n",
  2837. "val: loss: 0.000211, bce: 0.000598, dice: 1.001409\n",
  2838. "0m 9s\n",
  2839. "\n",
  2840. "\n",
  2841. "Epoch 184/799\n",
  2842. "----------\n",
  2843. "LR 0.0001\n",
  2844. "train: loss: 0.000221, bce: 0.000560, dice: 1.000734\n",
  2845. "val: loss: 0.000300, bce: 0.000760, dice: 1.000900\n",
  2846. "0m 9s\n",
  2847. "\n",
  2848. "\n",
  2849. "Epoch 185/799\n",
  2850. "----------\n",
  2851. "LR 0.0001\n",
  2852. "train: loss: 0.000252, bce: 0.000638, dice: 1.000615\n",
  2853. "val: loss: 0.000241, bce: 0.000595, dice: 1.001227\n",
  2854. "0m 9s\n",
  2855. "\n",
  2856. "\n",
  2857. "Epoch 186/799\n",
  2858. "----------\n",
  2859. "LR 0.0001\n",
  2860. "train: loss: 0.000222, bce: 0.000563, dice: 1.000683\n",
  2861. "val: loss: 0.000345, bce: 0.000670, dice: 1.001065\n",
  2862. "0m 9s\n",
  2863. "\n",
  2864. "\n",
  2865. "Epoch 187/799\n",
  2866. "----------\n",
  2867. "LR 0.0001\n",
  2868. "train: loss: 0.000286, bce: 0.000671, dice: 1.000673\n",
  2869. "val: loss: 0.000320, bce: 0.000723, dice: 1.000922\n",
  2870. "0m 9s\n",
  2871. "\n",
  2872. "\n",
  2873. "Epoch 188/799\n",
  2874. "----------\n",
  2875. "LR 0.0001\n",
  2876. "train: loss: 0.000216, bce: 0.000578, dice: 1.000574\n",
  2877. "val: loss: 0.000205, bce: 0.000576, dice: 1.001348\n",
  2878. "saving best model\n",
  2879. "0m 9s\n",
  2880. "\n",
  2881. "\n",
  2882. "Epoch 189/799\n",
  2883. "----------\n",
  2884. "LR 0.0001\n",
  2885. "train: loss: 0.000200, bce: 0.000519, dice: 1.000679\n",
  2886. "val: loss: 0.000265, bce: 0.000599, dice: 1.001068\n",
  2887. "0m 9s\n",
  2888. "\n",
  2889. "\n",
  2890. "Epoch 190/799\n",
  2891. "----------\n",
  2892. "LR 0.0001\n",
  2893. "train: loss: 0.000254, bce: 0.000619, dice: 1.000647\n",
  2894. "val: loss: 0.000231, bce: 0.000580, dice: 1.001178\n",
  2895. "0m 9s\n",
  2896. "\n",
  2897. "\n",
  2898. "Epoch 191/799\n",
  2899. "----------\n",
  2900. "LR 0.0001\n",
  2901. "train: loss: 0.000198, bce: 0.000510, dice: 1.000656\n",
  2902. "val: loss: 0.000214, bce: 0.000538, dice: 1.001234\n",
  2903. "0m 9s\n",
  2904. "\n",
  2905. "\n",
  2906. "Epoch 192/799\n",
  2907. "----------\n",
  2908. "LR 0.0001\n",
  2909. "train: loss: 0.000190, bce: 0.000485, dice: 1.000681\n",
  2910. "val: loss: 0.000203, bce: 0.000513, dice: 1.001312\n",
  2911. "saving best model\n",
  2912. "0m 9s\n",
  2913. "\n",
  2914. "\n",
  2915. "Epoch 193/799\n",
  2916. "----------\n",
  2917. "LR 0.0001\n",
  2918. "train: loss: 0.000189, bce: 0.000475, dice: 1.000686\n",
  2919. "val: loss: 0.000199, bce: 0.000495, dice: 1.001411\n",
  2920. "saving best model\n",
  2921. "0m 9s\n",
  2922. "\n",
  2923. "\n",
  2924. "Epoch 194/799\n",
  2925. "----------\n",
  2926. "LR 0.0001\n",
  2927. "train: loss: 0.000211, bce: 0.000499, dice: 1.000703\n",
  2928. "val: loss: 0.000322, bce: 0.000657, dice: 1.000974\n",
  2929. "0m 9s\n",
  2930. "\n",
  2931. "\n",
  2932. "Epoch 195/799\n",
  2933. "----------\n",
  2934. "LR 0.0001\n",
  2935. "train: loss: 0.000330, bce: 0.000810, dice: 1.000585\n",
  2936. "val: loss: 0.000293, bce: 0.000703, dice: 1.000924\n",
  2937. "0m 9s\n",
  2938. "\n",
  2939. "\n",
  2940. "Epoch 196/799\n",
  2941. "----------\n",
  2942. "LR 0.0001\n",
  2943. "train: loss: 0.000217, bce: 0.000569, dice: 1.000609\n",
  2944. "val: loss: 0.000214, bce: 0.000559, dice: 1.001227\n",
  2945. "0m 9s\n",
  2946. "\n",
  2947. "\n",
  2948. "Epoch 197/799\n",
  2949. "----------\n",
  2950. "LR 0.0001\n",
  2951. "train: loss: 0.000195, bce: 0.000500, dice: 1.000674\n",
  2952. "val: loss: 0.000226, bce: 0.000541, dice: 1.001161\n",
  2953. "0m 9s\n",
  2954. "\n",
  2955. "\n",
  2956. "Epoch 198/799\n",
  2957. "----------\n",
  2958. "LR 0.0001\n",
  2959. "train: loss: 0.000246, bce: 0.000585, dice: 1.000697\n",
  2960. "val: loss: 0.000288, bce: 0.000716, dice: 1.000830\n",
  2961. "0m 9s\n",
  2962. "\n",
  2963. "\n",
  2964. "Epoch 199/799\n",
  2965. "----------\n",
  2966. "LR 1e-05\n",
  2967. "train: loss: 0.000274, bce: 0.000649, dice: 1.000411\n",
  2968. "val: loss: 0.000235, bce: 0.000667, dice: 1.000989\n",
  2969. "0m 9s\n",
  2970. "\n",
  2971. "\n",
  2972. "Epoch 200/799\n",
  2973. "----------\n",
  2974. "LR 1e-05\n",
  2975. "train: loss: 0.000230, bce: 0.000608, dice: 1.000495\n",
  2976. "val: loss: 0.000221, bce: 0.000641, dice: 1.001085\n",
  2977. "0m 9s\n",
  2978. "\n",
  2979. "\n",
  2980. "Epoch 201/799\n",
  2981. "----------\n",
  2982. "LR 1e-05\n",
  2983. "train: loss: 0.000212, bce: 0.000580, dice: 1.000548\n",
  2984. "val: loss: 0.000214, bce: 0.000619, dice: 1.001147\n",
  2985. "0m 9s\n",
  2986. "\n",
  2987. "\n",
  2988. "Epoch 202/799\n",
  2989. "----------\n",
  2990. "LR 1e-05\n",
  2991. "train: loss: 0.000204, bce: 0.000561, dice: 1.000582\n",
  2992. "val: loss: 0.000209, bce: 0.000600, dice: 1.001185\n",
  2993. "0m 9s\n",
  2994. "\n",
  2995. "\n",
  2996. "Epoch 203/799\n",
  2997. "----------\n",
  2998. "LR 1e-05\n",
  2999. "train: loss: 0.000198, bce: 0.000543, dice: 1.000600\n",
  3000. "val: loss: 0.000206, bce: 0.000584, dice: 1.001216\n",
  3001. "0m 9s\n",
  3002. "\n",
  3003. "\n",
  3004. "Epoch 204/799\n",
  3005. "----------\n",
  3006. "LR 1e-05\n",
  3007. "train: loss: 0.000195, bce: 0.000530, dice: 1.000615\n",
  3008. "val: loss: 0.000203, bce: 0.000571, dice: 1.001240\n",
  3009. "0m 9s\n",
  3010. "\n",
  3011. "\n",
  3012. "Epoch 205/799\n",
  3013. "----------\n",
  3014. "LR 1e-05\n",
  3015. "train: loss: 0.000192, bce: 0.000519, dice: 1.000630\n",
  3016. "val: loss: 0.000200, bce: 0.000559, dice: 1.001252\n",
  3017. "0m 9s\n",
  3018. "\n",
  3019. "\n",
  3020. "Epoch 206/799\n",
  3021. "----------\n",
  3022. "LR 1e-05\n",
  3023. "train: loss: 0.000191, bce: 0.000509, dice: 1.000635\n",
  3024. "val: loss: 0.000198, bce: 0.000549, dice: 1.001266\n",
  3025. "saving best model\n",
  3026. "0m 9s\n",
  3027. "\n",
  3028. "\n",
  3029. "Epoch 207/799\n",
  3030. "----------\n",
  3031. "LR 1e-05\n",
  3032. "train: loss: 0.000189, bce: 0.000502, dice: 1.000645\n",
  3033. "val: loss: 0.000197, bce: 0.000540, dice: 1.001271\n",
  3034. "saving best model\n",
  3035. "0m 9s\n",
  3036. "\n",
  3037. "\n",
  3038. "Epoch 208/799\n",
  3039. "----------\n",
  3040. "LR 1e-05\n",
  3041. "train: loss: 0.000187, bce: 0.000494, dice: 1.000648\n",
  3042. "val: loss: 0.000196, bce: 0.000533, dice: 1.001281\n",
  3043. "saving best model\n",
  3044. "0m 9s\n",
  3045. "\n",
  3046. "\n",
  3047. "Epoch 209/799\n",
  3048. "----------\n",
  3049. "LR 1e-05\n",
  3050. "train: loss: 0.000186, bce: 0.000487, dice: 1.000653\n",
  3051. "val: loss: 0.000195, bce: 0.000526, dice: 1.001288\n",
  3052. "saving best model\n",
  3053. "0m 9s\n",
  3054. "\n",
  3055. "\n",
  3056. "Epoch 210/799\n",
  3057. "----------\n",
  3058. "LR 1e-05\n",
  3059. "train: loss: 0.000186, bce: 0.000482, dice: 1.000656\n",
  3060. "val: loss: 0.000195, bce: 0.000520, dice: 1.001293\n",
  3061. "saving best model\n",
  3062. "0m 9s\n",
  3063. "\n",
  3064. "\n",
  3065. "Epoch 211/799\n",
  3066. "----------\n",
  3067. "LR 1e-05\n",
  3068. "train: loss: 0.000185, bce: 0.000477, dice: 1.000662\n",
  3069. "val: loss: 0.000194, bce: 0.000515, dice: 1.001297\n",
  3070. "saving best model\n",
  3071. "0m 9s\n",
  3072. "\n",
  3073. "\n",
  3074. "Epoch 212/799\n",
  3075. "----------\n",
  3076. "LR 1e-05\n",
  3077. "train: loss: 0.000184, bce: 0.000472, dice: 1.000662\n",
  3078. "val: loss: 0.000193, bce: 0.000511, dice: 1.001308\n",
  3079. "saving best model\n",
  3080. "0m 9s\n",
  3081. "\n",
  3082. "\n",
  3083. "Epoch 213/799\n",
  3084. "----------\n",
  3085. "LR 1e-05\n",
  3086. "train: loss: 0.000183, bce: 0.000468, dice: 1.000665\n",
  3087. "val: loss: 0.000193, bce: 0.000507, dice: 1.001315\n",
  3088. "saving best model\n",
  3089. "0m 9s\n",
  3090. "\n",
  3091. "\n",
  3092. "Epoch 214/799\n",
  3093. "----------\n",
  3094. "LR 1e-05\n",
  3095. "train: loss: 0.000183, bce: 0.000465, dice: 1.000668\n",
  3096. "val: loss: 0.000193, bce: 0.000503, dice: 1.001321\n",
  3097. "saving best model\n",
  3098. "0m 9s\n",
  3099. "\n",
  3100. "\n",
  3101. "Epoch 215/799\n",
  3102. "----------\n",
  3103. "LR 1e-05\n",
  3104. "train: loss: 0.000182, bce: 0.000462, dice: 1.000670\n",
  3105. "val: loss: 0.000192, bce: 0.000500, dice: 1.001326\n",
  3106. "saving best model\n",
  3107. "0m 9s\n",
  3108. "\n",
  3109. "\n",
  3110. "Epoch 216/799\n",
  3111. "----------\n",
  3112. "LR 1e-05\n",
  3113. "train: loss: 0.000182, bce: 0.000458, dice: 1.000674\n",
  3114. "val: loss: 0.000192, bce: 0.000497, dice: 1.001329\n",
  3115. "saving best model\n",
  3116. "0m 9s\n",
  3117. "\n",
  3118. "\n",
  3119. "Epoch 217/799\n",
  3120. "----------\n",
  3121. "LR 1e-05\n",
  3122. "train: loss: 0.000182, bce: 0.000457, dice: 1.000674\n",
  3123. "val: loss: 0.000192, bce: 0.000494, dice: 1.001336\n",
  3124. "saving best model\n",
  3125. "0m 9s\n",
  3126. "\n",
  3127. "\n",
  3128. "Epoch 218/799\n",
  3129. "----------\n",
  3130. "LR 1e-05\n",
  3131. "train: loss: 0.000181, bce: 0.000454, dice: 1.000679\n",
  3132. "val: loss: 0.000191, bce: 0.000491, dice: 1.001334\n",
  3133. "saving best model\n",
  3134. "0m 9s\n",
  3135. "\n",
  3136. "\n",
  3137. "Epoch 219/799\n",
  3138. "----------\n",
  3139. "LR 1e-05\n",
  3140. "train: loss: 0.000181, bce: 0.000451, dice: 1.000675\n",
  3141. "val: loss: 0.000191, bce: 0.000489, dice: 1.001350\n",
  3142. "saving best model\n",
  3143. "0m 9s\n",
  3144. "\n",
  3145. "\n",
  3146. "Epoch 220/799\n",
  3147. "----------\n",
  3148. "LR 1e-05\n",
  3149. "train: loss: 0.000180, bce: 0.000449, dice: 1.000684\n",
  3150. "val: loss: 0.000191, bce: 0.000486, dice: 1.001346\n",
  3151. "saving best model\n",
  3152. "0m 9s\n",
  3153. "\n",
  3154. "\n",
  3155. "Epoch 221/799\n",
  3156. "----------\n",
  3157. "LR 1e-05\n",
  3158. "train: loss: 0.000180, bce: 0.000446, dice: 1.000677\n",
  3159. "val: loss: 0.000190, bce: 0.000485, dice: 1.001363\n",
  3160. "saving best model\n",
  3161. "0m 9s\n",
  3162. "\n",
  3163. "\n",
  3164. "Epoch 222/799\n",
  3165. "----------\n",
  3166. "LR 1e-05\n",
  3167. "train: loss: 0.000180, bce: 0.000446, dice: 1.000687\n",
  3168. "val: loss: 0.000190, bce: 0.000482, dice: 1.001355\n",
  3169. "saving best model\n",
  3170. "0m 9s\n",
  3171. "\n",
  3172. "\n",
  3173. "Epoch 223/799\n",
  3174. "----------\n",
  3175. "LR 1e-05\n",
  3176. "train: loss: 0.000180, bce: 0.000444, dice: 1.000687\n",
  3177. "val: loss: 0.000190, bce: 0.000480, dice: 1.001351\n",
  3178. "saving best model\n",
  3179. "0m 9s\n",
  3180. "\n",
  3181. "\n",
  3182. "Epoch 224/799\n",
  3183. "----------\n",
  3184. "LR 1e-05\n",
  3185. "train: loss: 0.000179, bce: 0.000442, dice: 1.000684\n",
  3186. "val: loss: 0.000190, bce: 0.000479, dice: 1.001360\n",
  3187. "saving best model\n",
  3188. "0m 9s\n",
  3189. "\n",
  3190. "\n",
  3191. "Epoch 225/799\n",
  3192. "----------\n",
  3193. "LR 1e-05\n",
  3194. "train: loss: 0.000179, bce: 0.000441, dice: 1.000691\n",
  3195. "val: loss: 0.000190, bce: 0.000477, dice: 1.001355\n",
  3196. "saving best model\n",
  3197. "0m 9s\n",
  3198. "\n",
  3199. "\n",
  3200. "Epoch 226/799\n",
  3201. "----------\n",
  3202. "LR 1e-05\n",
  3203. "train: loss: 0.000179, bce: 0.000438, dice: 1.000686\n",
  3204. "val: loss: 0.000189, bce: 0.000476, dice: 1.001366\n",
  3205. "saving best model\n",
  3206. "0m 9s\n",
  3207. "\n",
  3208. "\n",
  3209. "Epoch 227/799\n",
  3210. "----------\n",
  3211. "LR 1e-05\n",
  3212. "train: loss: 0.000178, bce: 0.000437, dice: 1.000688\n",
  3213. "val: loss: 0.000189, bce: 0.000475, dice: 1.001376\n",
  3214. "saving best model\n",
  3215. "0m 9s\n",
  3216. "\n",
  3217. "\n",
  3218. "Epoch 228/799\n",
  3219. "----------\n",
  3220. "LR 1e-05\n",
  3221. "train: loss: 0.000178, bce: 0.000437, dice: 1.000691\n",
  3222. "val: loss: 0.000189, bce: 0.000474, dice: 1.001373\n",
  3223. "saving best model\n",
  3224. "0m 9s\n",
  3225. "\n",
  3226. "\n",
  3227. "Epoch 229/799\n",
  3228. "----------\n",
  3229. "LR 1e-05\n",
  3230. "train: loss: 0.000178, bce: 0.000436, dice: 1.000692\n",
  3231. "val: loss: 0.000189, bce: 0.000472, dice: 1.001368\n",
  3232. "saving best model\n",
  3233. "0m 9s\n",
  3234. "\n",
  3235. "\n",
  3236. "Epoch 230/799\n",
  3237. "----------\n",
  3238. "LR 1e-05\n",
  3239. "train: loss: 0.000178, bce: 0.000434, dice: 1.000693\n",
  3240. "val: loss: 0.000188, bce: 0.000470, dice: 1.001367\n",
  3241. "saving best model\n",
  3242. "0m 9s\n",
  3243. "\n",
  3244. "\n",
  3245. "Epoch 231/799\n",
  3246. "----------\n",
  3247. "LR 1e-05\n",
  3248. "train: loss: 0.000178, bce: 0.000433, dice: 1.000691\n",
  3249. "val: loss: 0.000188, bce: 0.000470, dice: 1.001376\n",
  3250. "saving best model\n",
  3251. "0m 9s\n",
  3252. "\n",
  3253. "\n",
  3254. "Epoch 232/799\n",
  3255. "----------\n",
  3256. "LR 1e-05\n",
  3257. "train: loss: 0.000178, bce: 0.000433, dice: 1.000694\n",
  3258. "val: loss: 0.000188, bce: 0.000469, dice: 1.001372\n",
  3259. "saving best model\n",
  3260. "0m 9s\n",
  3261. "\n",
  3262. "\n",
  3263. "Epoch 233/799\n",
  3264. "----------\n",
  3265. "LR 1e-05\n",
  3266. "train: loss: 0.000177, bce: 0.000432, dice: 1.000696\n",
  3267. "val: loss: 0.000188, bce: 0.000468, dice: 1.001367\n",
  3268. "saving best model\n",
  3269. "0m 9s\n",
  3270. "\n",
  3271. "\n",
  3272. "Epoch 234/799\n",
  3273. "----------\n",
  3274. "LR 1e-05\n",
  3275. "train: loss: 0.000177, bce: 0.000431, dice: 1.000693\n",
  3276. "val: loss: 0.000188, bce: 0.000466, dice: 1.001371\n",
  3277. "saving best model\n",
  3278. "0m 9s\n",
  3279. "\n",
  3280. "\n",
  3281. "Epoch 235/799\n",
  3282. "----------\n",
  3283. "LR 1e-05\n",
  3284. "train: loss: 0.000177, bce: 0.000430, dice: 1.000694\n",
  3285. "val: loss: 0.000187, bce: 0.000466, dice: 1.001375\n",
  3286. "saving best model\n",
  3287. "0m 9s\n",
  3288. "\n",
  3289. "\n",
  3290. "Epoch 236/799\n",
  3291. "----------\n",
  3292. "LR 1e-05\n",
  3293. "train: loss: 0.000177, bce: 0.000429, dice: 1.000698\n",
  3294. "val: loss: 0.000187, bce: 0.000464, dice: 1.001371\n",
  3295. "saving best model\n",
  3296. "0m 9s\n",
  3297. "\n",
  3298. "\n",
  3299. "Epoch 237/799\n",
  3300. "----------\n",
  3301. "LR 1e-05\n",
  3302. "train: loss: 0.000176, bce: 0.000428, dice: 1.000697\n",
  3303. "val: loss: 0.000187, bce: 0.000464, dice: 1.001374\n",
  3304. "saving best model\n",
  3305. "0m 9s\n",
  3306. "\n",
  3307. "\n",
  3308. "Epoch 238/799\n",
  3309. "----------\n",
  3310. "LR 1e-05\n",
  3311. "train: loss: 0.000176, bce: 0.000427, dice: 1.000698\n",
  3312. "val: loss: 0.000187, bce: 0.000463, dice: 1.001377\n",
  3313. "saving best model\n",
  3314. "0m 9s\n",
  3315. "\n",
  3316. "\n",
  3317. "Epoch 239/799\n",
  3318. "----------\n",
  3319. "LR 1e-05\n",
  3320. "train: loss: 0.000176, bce: 0.000427, dice: 1.000695\n",
  3321. "val: loss: 0.000186, bce: 0.000462, dice: 1.001387\n",
  3322. "saving best model\n",
  3323. "0m 9s\n",
  3324. "\n",
  3325. "\n",
  3326. "Epoch 240/799\n",
  3327. "----------\n",
  3328. "LR 1e-05\n",
  3329. "train: loss: 0.000176, bce: 0.000426, dice: 1.000698\n",
  3330. "val: loss: 0.000186, bce: 0.000461, dice: 1.001382\n",
  3331. "saving best model\n",
  3332. "0m 9s\n",
  3333. "\n",
  3334. "\n",
  3335. "Epoch 241/799\n",
  3336. "----------\n",
  3337. "LR 1e-05\n",
  3338. "train: loss: 0.000175, bce: 0.000424, dice: 1.000699\n",
  3339. "val: loss: 0.000186, bce: 0.000460, dice: 1.001383\n",
  3340. "saving best model\n",
  3341. "0m 9s\n",
  3342. "\n",
  3343. "\n",
  3344. "Epoch 242/799\n",
  3345. "----------\n",
  3346. "LR 1e-05\n",
  3347. "train: loss: 0.000176, bce: 0.000424, dice: 1.000699\n",
  3348. "val: loss: 0.000186, bce: 0.000459, dice: 1.001382\n",
  3349. "saving best model\n",
  3350. "0m 9s\n",
  3351. "\n",
  3352. "\n",
  3353. "Epoch 243/799\n",
  3354. "----------\n",
  3355. "LR 1e-05\n",
  3356. "train: loss: 0.000175, bce: 0.000423, dice: 1.000698\n",
  3357. "val: loss: 0.000186, bce: 0.000458, dice: 1.001387\n",
  3358. "saving best model\n",
  3359. "0m 9s\n",
  3360. "\n",
  3361. "\n",
  3362. "Epoch 244/799\n",
  3363. "----------\n",
  3364. "LR 1e-05\n",
  3365. "train: loss: 0.000175, bce: 0.000422, dice: 1.000702\n",
  3366. "val: loss: 0.000185, bce: 0.000458, dice: 1.001382\n",
  3367. "saving best model\n",
  3368. "0m 9s\n",
  3369. "\n",
  3370. "\n",
  3371. "Epoch 245/799\n",
  3372. "----------\n",
  3373. "LR 1e-05\n",
  3374. "train: loss: 0.000175, bce: 0.000421, dice: 1.000700\n",
  3375. "val: loss: 0.000185, bce: 0.000457, dice: 1.001387\n",
  3376. "saving best model\n",
  3377. "0m 9s\n",
  3378. "\n",
  3379. "\n",
  3380. "Epoch 246/799\n",
  3381. "----------\n",
  3382. "LR 1e-05\n",
  3383. "train: loss: 0.000175, bce: 0.000421, dice: 1.000699\n",
  3384. "val: loss: 0.000185, bce: 0.000457, dice: 1.001392\n",
  3385. "saving best model\n",
  3386. "0m 9s\n",
  3387. "\n",
  3388. "\n",
  3389. "Epoch 247/799\n",
  3390. "----------\n",
  3391. "LR 1e-05\n",
  3392. "train: loss: 0.000174, bce: 0.000421, dice: 1.000700\n",
  3393. "val: loss: 0.000185, bce: 0.000455, dice: 1.001383\n",
  3394. "saving best model\n",
  3395. "0m 9s\n",
  3396. "\n",
  3397. "\n",
  3398. "Epoch 248/799\n",
  3399. "----------\n",
  3400. "LR 1e-05\n",
  3401. "train: loss: 0.000174, bce: 0.000419, dice: 1.000698\n",
  3402. "val: loss: 0.000185, bce: 0.000455, dice: 1.001398\n",
  3403. "saving best model\n",
  3404. "0m 9s\n",
  3405. "\n",
  3406. "\n",
  3407. "Epoch 249/799\n",
  3408. "----------\n",
  3409. "LR 1e-05\n",
  3410. "train: loss: 0.000174, bce: 0.000419, dice: 1.000702\n",
  3411. "val: loss: 0.000184, bce: 0.000454, dice: 1.001382\n",
  3412. "saving best model\n",
  3413. "0m 9s\n",
  3414. "\n",
  3415. "\n",
  3416. "Epoch 250/799\n",
  3417. "----------\n",
  3418. "LR 1e-05\n",
  3419. "train: loss: 0.000173, bce: 0.000417, dice: 1.000699\n",
  3420. "val: loss: 0.000184, bce: 0.000454, dice: 1.001394\n",
  3421. "saving best model\n",
  3422. "0m 9s\n",
  3423. "\n",
  3424. "\n",
  3425. "Epoch 251/799\n",
  3426. "----------\n",
  3427. "LR 1e-05\n",
  3428. "train: loss: 0.000173, bce: 0.000417, dice: 1.000703\n",
  3429. "val: loss: 0.000184, bce: 0.000452, dice: 1.001374\n",
  3430. "saving best model\n",
  3431. "0m 9s\n",
  3432. "\n",
  3433. "\n",
  3434. "Epoch 252/799\n",
  3435. "----------\n",
  3436. "LR 1e-05\n",
  3437. "train: loss: 0.000173, bce: 0.000416, dice: 1.000703\n",
  3438. "val: loss: 0.000184, bce: 0.000452, dice: 1.001371\n",
  3439. "saving best model\n",
  3440. "0m 9s\n",
  3441. "\n",
  3442. "\n",
  3443. "Epoch 253/799\n",
  3444. "----------\n",
  3445. "LR 1e-05\n",
  3446. "train: loss: 0.000173, bce: 0.000416, dice: 1.000697\n",
  3447. "val: loss: 0.000184, bce: 0.000452, dice: 1.001399\n",
  3448. "saving best model\n",
  3449. "0m 9s\n",
  3450. "\n",
  3451. "\n",
  3452. "Epoch 254/799\n",
  3453. "----------\n",
  3454. "LR 1e-05\n",
  3455. "train: loss: 0.000173, bce: 0.000415, dice: 1.000702\n",
  3456. "val: loss: 0.000183, bce: 0.000451, dice: 1.001388\n",
  3457. "saving best model\n",
  3458. "0m 9s\n",
  3459. "\n",
  3460. "\n",
  3461. "Epoch 255/799\n",
  3462. "----------\n",
  3463. "LR 1e-05\n",
  3464. "train: loss: 0.000173, bce: 0.000414, dice: 1.000701\n",
  3465. "val: loss: 0.000183, bce: 0.000450, dice: 1.001387\n",
  3466. "saving best model\n",
  3467. "0m 9s\n",
  3468. "\n",
  3469. "\n",
  3470. "Epoch 256/799\n",
  3471. "----------\n",
  3472. "LR 1e-05\n",
  3473. "train: loss: 0.000173, bce: 0.000415, dice: 1.000701\n",
  3474. "val: loss: 0.000183, bce: 0.000450, dice: 1.001389\n",
  3475. "saving best model\n",
  3476. "0m 9s\n",
  3477. "\n",
  3478. "\n",
  3479. "Epoch 257/799\n",
  3480. "----------\n",
  3481. "LR 1e-05\n",
  3482. "train: loss: 0.000172, bce: 0.000414, dice: 1.000704\n",
  3483. "val: loss: 0.000183, bce: 0.000448, dice: 1.001375\n",
  3484. "0m 9s\n",
  3485. "\n",
  3486. "\n",
  3487. "Epoch 258/799\n",
  3488. "----------\n",
  3489. "LR 1e-05\n",
  3490. "train: loss: 0.000172, bce: 0.000412, dice: 1.000700\n",
  3491. "val: loss: 0.000182, bce: 0.000447, dice: 1.001384\n",
  3492. "saving best model\n",
  3493. "0m 9s\n",
  3494. "\n",
  3495. "\n",
  3496. "Epoch 259/799\n",
  3497. "----------\n",
  3498. "LR 1e-05\n",
  3499. "train: loss: 0.000172, bce: 0.000412, dice: 1.000703\n",
  3500. "val: loss: 0.000182, bce: 0.000447, dice: 1.001378\n",
  3501. "saving best model\n",
  3502. "0m 9s\n",
  3503. "\n",
  3504. "\n",
  3505. "Epoch 260/799\n",
  3506. "----------\n",
  3507. "LR 1e-05\n",
  3508. "train: loss: 0.000172, bce: 0.000412, dice: 1.000699\n",
  3509. "val: loss: 0.000182, bce: 0.000447, dice: 1.001390\n",
  3510. "saving best model\n",
  3511. "0m 9s\n",
  3512. "\n",
  3513. "\n",
  3514. "Epoch 261/799\n",
  3515. "----------\n",
  3516. "LR 1e-05\n",
  3517. "train: loss: 0.000172, bce: 0.000411, dice: 1.000705\n",
  3518. "val: loss: 0.000182, bce: 0.000445, dice: 1.001366\n",
  3519. "0m 9s\n",
  3520. "\n",
  3521. "\n",
  3522. "Epoch 262/799\n",
  3523. "----------\n",
  3524. "LR 1e-05\n",
  3525. "train: loss: 0.000172, bce: 0.000410, dice: 1.000701\n",
  3526. "val: loss: 0.000181, bce: 0.000445, dice: 1.001380\n",
  3527. "saving best model\n",
  3528. "0m 9s\n",
  3529. "\n",
  3530. "\n",
  3531. "Epoch 263/799\n",
  3532. "----------\n",
  3533. "LR 1e-05\n",
  3534. "train: loss: 0.000171, bce: 0.000410, dice: 1.000702\n",
  3535. "val: loss: 0.000181, bce: 0.000444, dice: 1.001384\n",
  3536. "saving best model\n",
  3537. "0m 9s\n",
  3538. "\n",
  3539. "\n",
  3540. "Epoch 264/799\n",
  3541. "----------\n",
  3542. "LR 1e-05\n",
  3543. "train: loss: 0.000171, bce: 0.000409, dice: 1.000698\n",
  3544. "val: loss: 0.000181, bce: 0.000445, dice: 1.001406\n",
  3545. "0m 9s\n",
  3546. "\n",
  3547. "\n",
  3548. "Epoch 265/799\n",
  3549. "----------\n",
  3550. "LR 1e-05\n",
  3551. "train: loss: 0.000171, bce: 0.000409, dice: 1.000708\n",
  3552. "val: loss: 0.000181, bce: 0.000443, dice: 1.001370\n",
  3553. "saving best model\n",
  3554. "0m 9s\n",
  3555. "\n",
  3556. "\n",
  3557. "Epoch 266/799\n",
  3558. "----------\n",
  3559. "LR 1e-05\n",
  3560. "train: loss: 0.000171, bce: 0.000408, dice: 1.000700\n",
  3561. "val: loss: 0.000180, bce: 0.000443, dice: 1.001379\n",
  3562. "saving best model\n",
  3563. "0m 9s\n",
  3564. "\n",
  3565. "\n",
  3566. "Epoch 267/799\n",
  3567. "----------\n",
  3568. "LR 1e-05\n",
  3569. "train: loss: 0.000171, bce: 0.000408, dice: 1.000699\n",
  3570. "val: loss: 0.000180, bce: 0.000442, dice: 1.001381\n",
  3571. "saving best model\n",
  3572. "0m 9s\n",
  3573. "\n",
  3574. "\n",
  3575. "Epoch 268/799\n",
  3576. "----------\n",
  3577. "LR 1e-05\n",
  3578. "train: loss: 0.000170, bce: 0.000407, dice: 1.000701\n",
  3579. "val: loss: 0.000180, bce: 0.000441, dice: 1.001377\n",
  3580. "saving best model\n",
  3581. "0m 9s\n",
  3582. "\n",
  3583. "\n",
  3584. "Epoch 269/799\n",
  3585. "----------\n",
  3586. "LR 1e-05\n",
  3587. "train: loss: 0.000170, bce: 0.000405, dice: 1.000702\n",
  3588. "val: loss: 0.000180, bce: 0.000441, dice: 1.001378\n",
  3589. "saving best model\n",
  3590. "0m 9s\n",
  3591. "\n",
  3592. "\n",
  3593. "Epoch 270/799\n",
  3594. "----------\n",
  3595. "LR 1e-05\n",
  3596. "train: loss: 0.000170, bce: 0.000404, dice: 1.000702\n",
  3597. "val: loss: 0.000180, bce: 0.000440, dice: 1.001376\n",
  3598. "saving best model\n",
  3599. "0m 9s\n",
  3600. "\n",
  3601. "\n",
  3602. "Epoch 271/799\n",
  3603. "----------\n",
  3604. "LR 1e-05\n",
  3605. "train: loss: 0.000170, bce: 0.000405, dice: 1.000701\n",
  3606. "val: loss: 0.000179, bce: 0.000439, dice: 1.001370\n",
  3607. "saving best model\n",
  3608. "0m 9s\n",
  3609. "\n",
  3610. "\n",
  3611. "Epoch 272/799\n",
  3612. "----------\n",
  3613. "LR 1e-05\n",
  3614. "train: loss: 0.000170, bce: 0.000404, dice: 1.000703\n",
  3615. "val: loss: 0.000179, bce: 0.000439, dice: 1.001379\n",
  3616. "saving best model\n",
  3617. "0m 9s\n",
  3618. "\n",
  3619. "\n",
  3620. "Epoch 273/799\n",
  3621. "----------\n",
  3622. "LR 1e-05\n",
  3623. "train: loss: 0.000170, bce: 0.000404, dice: 1.000701\n",
  3624. "val: loss: 0.000179, bce: 0.000440, dice: 1.001385\n",
  3625. "saving best model\n",
  3626. "0m 9s\n",
  3627. "\n",
  3628. "\n",
  3629. "Epoch 274/799\n",
  3630. "----------\n",
  3631. "LR 1e-05\n",
  3632. "train: loss: 0.000170, bce: 0.000404, dice: 1.000701\n",
  3633. "val: loss: 0.000178, bce: 0.000438, dice: 1.001382\n",
  3634. "saving best model\n",
  3635. "0m 9s\n",
  3636. "\n",
  3637. "\n",
  3638. "Epoch 275/799\n",
  3639. "----------\n",
  3640. "LR 1e-05\n",
  3641. "train: loss: 0.000169, bce: 0.000403, dice: 1.000701\n",
  3642. "val: loss: 0.000178, bce: 0.000438, dice: 1.001372\n",
  3643. "0m 9s\n",
  3644. "\n",
  3645. "\n",
  3646. "Epoch 276/799\n",
  3647. "----------\n",
  3648. "LR 1e-05\n",
  3649. "train: loss: 0.000169, bce: 0.000403, dice: 1.000700\n",
  3650. "val: loss: 0.000178, bce: 0.000436, dice: 1.001381\n",
  3651. "saving best model\n",
  3652. "0m 9s\n",
  3653. "\n",
  3654. "\n",
  3655. "Epoch 277/799\n",
  3656. "----------\n",
  3657. "LR 1e-05\n",
  3658. "train: loss: 0.000168, bce: 0.000401, dice: 1.000702\n",
  3659. "val: loss: 0.000178, bce: 0.000437, dice: 1.001388\n",
  3660. "saving best model\n",
  3661. "0m 9s\n",
  3662. "\n",
  3663. "\n",
  3664. "Epoch 278/799\n",
  3665. "----------\n",
  3666. "LR 1e-05\n",
  3667. "train: loss: 0.000168, bce: 0.000401, dice: 1.000703\n",
  3668. "val: loss: 0.000178, bce: 0.000435, dice: 1.001369\n",
  3669. "saving best model\n",
  3670. "0m 9s\n",
  3671. "\n",
  3672. "\n",
  3673. "Epoch 279/799\n",
  3674. "----------\n",
  3675. "LR 1e-05\n",
  3676. "train: loss: 0.000168, bce: 0.000399, dice: 1.000701\n",
  3677. "val: loss: 0.000177, bce: 0.000435, dice: 1.001382\n",
  3678. "saving best model\n",
  3679. "0m 9s\n",
  3680. "\n",
  3681. "\n",
  3682. "Epoch 280/799\n",
  3683. "----------\n",
  3684. "LR 1e-05\n",
  3685. "train: loss: 0.000168, bce: 0.000401, dice: 1.000703\n",
  3686. "val: loss: 0.000181, bce: 0.000436, dice: 1.001333\n",
  3687. "0m 9s\n",
  3688. "\n",
  3689. "\n",
  3690. "Epoch 281/799\n",
  3691. "----------\n",
  3692. "LR 1e-05\n",
  3693. "train: loss: 0.000169, bce: 0.000401, dice: 1.000703\n",
  3694. "val: loss: 0.000180, bce: 0.000436, dice: 1.001322\n",
  3695. "0m 9s\n",
  3696. "\n",
  3697. "\n",
  3698. "Epoch 282/799\n",
  3699. "----------\n",
  3700. "LR 1e-05\n",
  3701. "train: loss: 0.000168, bce: 0.000399, dice: 1.000694\n",
  3702. "val: loss: 0.000177, bce: 0.000434, dice: 1.001374\n",
  3703. "saving best model\n",
  3704. "0m 9s\n",
  3705. "\n",
  3706. "\n",
  3707. "Epoch 283/799\n",
  3708. "----------\n",
  3709. "LR 1e-05\n",
  3710. "train: loss: 0.000168, bce: 0.000398, dice: 1.000699\n",
  3711. "val: loss: 0.000176, bce: 0.000434, dice: 1.001367\n",
  3712. "saving best model\n",
  3713. "0m 9s\n",
  3714. "\n",
  3715. "\n",
  3716. "Epoch 284/799\n",
  3717. "----------\n",
  3718. "LR 1e-05\n",
  3719. "train: loss: 0.000167, bce: 0.000397, dice: 1.000704\n",
  3720. "val: loss: 0.000177, bce: 0.000431, dice: 1.001353\n",
  3721. "0m 9s\n",
  3722. "\n",
  3723. "\n",
  3724. "Epoch 285/799\n",
  3725. "----------\n",
  3726. "LR 1e-05\n",
  3727. "train: loss: 0.000168, bce: 0.000398, dice: 1.000701\n",
  3728. "val: loss: 0.000177, bce: 0.000431, dice: 1.001383\n",
  3729. "0m 9s\n",
  3730. "\n",
  3731. "\n",
  3732. "Epoch 286/799\n",
  3733. "----------\n",
  3734. "LR 1e-05\n",
  3735. "train: loss: 0.000168, bce: 0.000396, dice: 1.000702\n",
  3736. "val: loss: 0.000177, bce: 0.000431, dice: 1.001350\n",
  3737. "0m 9s\n",
  3738. "\n",
  3739. "\n",
  3740. "Epoch 287/799\n",
  3741. "----------\n",
  3742. "LR 1e-05\n",
  3743. "train: loss: 0.000169, bce: 0.000397, dice: 1.000700\n",
  3744. "val: loss: 0.000176, bce: 0.000433, dice: 1.001360\n",
  3745. "saving best model\n",
  3746. "0m 9s\n",
  3747. "\n",
  3748. "\n",
  3749. "Epoch 288/799\n",
  3750. "----------\n",
  3751. "LR 1e-05\n",
  3752. "train: loss: 0.000168, bce: 0.000398, dice: 1.000698\n",
  3753. "val: loss: 0.000178, bce: 0.000431, dice: 1.001343\n",
  3754. "0m 9s\n",
  3755. "\n",
  3756. "\n",
  3757. "Epoch 289/799\n",
  3758. "----------\n",
  3759. "LR 1e-05\n",
  3760. "train: loss: 0.000167, bce: 0.000395, dice: 1.000695\n",
  3761. "val: loss: 0.000175, bce: 0.000432, dice: 1.001387\n",
  3762. "saving best model\n",
  3763. "0m 9s\n",
  3764. "\n",
  3765. "\n",
  3766. "Epoch 290/799\n",
  3767. "----------\n",
  3768. "LR 1e-05\n",
  3769. "train: loss: 0.000167, bce: 0.000395, dice: 1.000696\n",
  3770. "val: loss: 0.000178, bce: 0.000437, dice: 1.001426\n",
  3771. "0m 9s\n",
  3772. "\n",
  3773. "\n",
  3774. "Epoch 291/799\n",
  3775. "----------\n",
  3776. "LR 1e-05\n",
  3777. "train: loss: 0.000167, bce: 0.000396, dice: 1.000705\n",
  3778. "val: loss: 0.000174, bce: 0.000430, dice: 1.001385\n",
  3779. "saving best model\n",
  3780. "0m 9s\n",
  3781. "\n",
  3782. "\n",
  3783. "Epoch 292/799\n",
  3784. "----------\n",
  3785. "LR 1e-05\n",
  3786. "train: loss: 0.000166, bce: 0.000394, dice: 1.000701\n",
  3787. "val: loss: 0.000174, bce: 0.000427, dice: 1.001364\n",
  3788. "saving best model\n",
  3789. "0m 9s\n",
  3790. "\n",
  3791. "\n",
  3792. "Epoch 293/799\n",
  3793. "----------\n",
  3794. "LR 1e-05\n",
  3795. "train: loss: 0.000167, bce: 0.000394, dice: 1.000703\n",
  3796. "val: loss: 0.000178, bce: 0.000429, dice: 1.001313\n",
  3797. "0m 9s\n",
  3798. "\n",
  3799. "\n",
  3800. "Epoch 294/799\n",
  3801. "----------\n",
  3802. "LR 1e-05\n",
  3803. "train: loss: 0.000167, bce: 0.000392, dice: 1.000707\n",
  3804. "val: loss: 0.000174, bce: 0.000427, dice: 1.001364\n",
  3805. "saving best model\n",
  3806. "0m 9s\n",
  3807. "\n",
  3808. "\n",
  3809. "Epoch 295/799\n",
  3810. "----------\n",
  3811. "LR 1e-05\n",
  3812. "train: loss: 0.000167, bce: 0.000394, dice: 1.000690\n",
  3813. "val: loss: 0.000175, bce: 0.000434, dice: 1.001362\n",
  3814. "0m 9s\n",
  3815. "\n",
  3816. "\n",
  3817. "Epoch 296/799\n",
  3818. "----------\n",
  3819. "LR 1e-05\n",
  3820. "train: loss: 0.000165, bce: 0.000393, dice: 1.000697\n",
  3821. "val: loss: 0.000173, bce: 0.000426, dice: 1.001361\n",
  3822. "saving best model\n",
  3823. "0m 9s\n",
  3824. "\n",
  3825. "\n",
  3826. "Epoch 297/799\n",
  3827. "----------\n",
  3828. "LR 1e-05\n",
  3829. "train: loss: 0.000165, bce: 0.000391, dice: 1.000699\n",
  3830. "val: loss: 0.000173, bce: 0.000427, dice: 1.001376\n",
  3831. "saving best model\n",
  3832. "0m 9s\n",
  3833. "\n",
  3834. "\n",
  3835. "Epoch 298/799\n",
  3836. "----------\n",
  3837. "LR 1e-05\n",
  3838. "train: loss: 0.000167, bce: 0.000392, dice: 1.000700\n",
  3839. "val: loss: 0.000174, bce: 0.000429, dice: 1.001411\n",
  3840. "0m 9s\n",
  3841. "\n",
  3842. "\n",
  3843. "Epoch 299/799\n",
  3844. "----------\n",
  3845. "LR 1e-05\n",
  3846. "train: loss: 0.000165, bce: 0.000390, dice: 1.000705\n",
  3847. "val: loss: 0.000174, bce: 0.000430, dice: 1.001395\n",
  3848. "0m 9s\n",
  3849. "\n",
  3850. "\n",
  3851. "Epoch 300/799\n",
  3852. "----------\n",
  3853. "LR 1e-05\n",
  3854. "train: loss: 0.000165, bce: 0.000392, dice: 1.000692\n",
  3855. "val: loss: 0.000174, bce: 0.000428, dice: 1.001412\n",
  3856. "0m 9s\n",
  3857. "\n",
  3858. "\n",
  3859. "Epoch 301/799\n",
  3860. "----------\n",
  3861. "LR 1e-05\n",
  3862. "train: loss: 0.000166, bce: 0.000391, dice: 1.000699\n",
  3863. "val: loss: 0.000173, bce: 0.000427, dice: 1.001372\n",
  3864. "saving best model\n",
  3865. "0m 9s\n",
  3866. "\n",
  3867. "\n",
  3868. "Epoch 302/799\n",
  3869. "----------\n",
  3870. "LR 1e-05\n",
  3871. "train: loss: 0.000166, bce: 0.000390, dice: 1.000694\n",
  3872. "val: loss: 0.000173, bce: 0.000424, dice: 1.001393\n",
  3873. "saving best model\n",
  3874. "0m 9s\n",
  3875. "\n",
  3876. "\n",
  3877. "Epoch 303/799\n",
  3878. "----------\n",
  3879. "LR 1e-05\n",
  3880. "train: loss: 0.000173, bce: 0.000399, dice: 1.000698\n",
  3881. "val: loss: 0.000175, bce: 0.000432, dice: 1.001419\n",
  3882. "0m 9s\n",
  3883. "\n",
  3884. "\n",
  3885. "Epoch 304/799\n",
  3886. "----------\n",
  3887. "LR 1e-05\n",
  3888. "train: loss: 0.000168, bce: 0.000396, dice: 1.000696\n",
  3889. "val: loss: 0.000172, bce: 0.000428, dice: 1.001327\n",
  3890. "saving best model\n",
  3891. "0m 9s\n",
  3892. "\n",
  3893. "\n",
  3894. "Epoch 305/799\n",
  3895. "----------\n",
  3896. "LR 1e-05\n",
  3897. "train: loss: 0.000165, bce: 0.000392, dice: 1.000694\n",
  3898. "val: loss: 0.000175, bce: 0.000425, dice: 1.001297\n",
  3899. "0m 9s\n",
  3900. "\n",
  3901. "\n",
  3902. "Epoch 306/799\n",
  3903. "----------\n",
  3904. "LR 1e-05\n",
  3905. "train: loss: 0.000165, bce: 0.000389, dice: 1.000693\n",
  3906. "val: loss: 0.000172, bce: 0.000421, dice: 1.001343\n",
  3907. "saving best model\n",
  3908. "0m 9s\n",
  3909. "\n",
  3910. "\n",
  3911. "Epoch 307/799\n",
  3912. "----------\n",
  3913. "LR 1e-05\n",
  3914. "train: loss: 0.000165, bce: 0.000388, dice: 1.000697\n",
  3915. "val: loss: 0.000171, bce: 0.000425, dice: 1.001334\n",
  3916. "saving best model\n",
  3917. "0m 9s\n",
  3918. "\n",
  3919. "\n",
  3920. "Epoch 308/799\n",
  3921. "----------\n",
  3922. "LR 1e-05\n",
  3923. "train: loss: 0.000163, bce: 0.000386, dice: 1.000692\n",
  3924. "val: loss: 0.000171, bce: 0.000420, dice: 1.001346\n",
  3925. "saving best model\n",
  3926. "0m 9s\n",
  3927. "\n",
  3928. "\n",
  3929. "Epoch 309/799\n",
  3930. "----------\n",
  3931. "LR 1e-05\n",
  3932. "train: loss: 0.000163, bce: 0.000386, dice: 1.000699\n",
  3933. "val: loss: 0.000171, bce: 0.000418, dice: 1.001321\n",
  3934. "0m 9s\n",
  3935. "\n",
  3936. "\n",
  3937. "Epoch 310/799\n",
  3938. "----------\n",
  3939. "LR 1e-05\n",
  3940. "train: loss: 0.000163, bce: 0.000383, dice: 1.000692\n",
  3941. "val: loss: 0.000170, bce: 0.000418, dice: 1.001341\n",
  3942. "saving best model\n",
  3943. "0m 9s\n",
  3944. "\n",
  3945. "\n",
  3946. "Epoch 311/799\n",
  3947. "----------\n",
  3948. "LR 1e-05\n",
  3949. "train: loss: 0.000162, bce: 0.000383, dice: 1.000695\n",
  3950. "val: loss: 0.000170, bce: 0.000416, dice: 1.001348\n",
  3951. "saving best model\n",
  3952. "0m 9s\n",
  3953. "\n",
  3954. "\n",
  3955. "Epoch 312/799\n",
  3956. "----------\n",
  3957. "LR 1e-05\n",
  3958. "train: loss: 0.000163, bce: 0.000383, dice: 1.000695\n",
  3959. "val: loss: 0.000170, bce: 0.000418, dice: 1.001362\n",
  3960. "saving best model\n",
  3961. "0m 9s\n",
  3962. "\n",
  3963. "\n",
  3964. "Epoch 313/799\n",
  3965. "----------\n",
  3966. "LR 1e-05\n",
  3967. "train: loss: 0.000163, bce: 0.000383, dice: 1.000697\n",
  3968. "val: loss: 0.000171, bce: 0.000418, dice: 1.001358\n",
  3969. "0m 9s\n",
  3970. "\n",
  3971. "\n",
  3972. "Epoch 314/799\n",
  3973. "----------\n",
  3974. "LR 1e-05\n",
  3975. "train: loss: 0.000167, bce: 0.000387, dice: 1.000691\n",
  3976. "val: loss: 0.000174, bce: 0.000431, dice: 1.001371\n",
  3977. "0m 9s\n",
  3978. "\n",
  3979. "\n",
  3980. "Epoch 315/799\n",
  3981. "----------\n",
  3982. "LR 1e-05\n",
  3983. "train: loss: 0.000164, bce: 0.000388, dice: 1.000693\n",
  3984. "val: loss: 0.000170, bce: 0.000418, dice: 1.001311\n",
  3985. "0m 9s\n",
  3986. "\n",
  3987. "\n",
  3988. "Epoch 316/799\n",
  3989. "----------\n",
  3990. "LR 1e-05\n",
  3991. "train: loss: 0.000163, bce: 0.000384, dice: 1.000692\n",
  3992. "val: loss: 0.000169, bce: 0.000415, dice: 1.001325\n",
  3993. "saving best model\n",
  3994. "0m 9s\n",
  3995. "\n",
  3996. "\n",
  3997. "Epoch 317/799\n",
  3998. "----------\n",
  3999. "LR 1e-05\n",
  4000. "train: loss: 0.000162, bce: 0.000382, dice: 1.000694\n",
  4001. "val: loss: 0.000171, bce: 0.000415, dice: 1.001302\n",
  4002. "0m 9s\n",
  4003. "\n",
  4004. "\n",
  4005. "Epoch 318/799\n",
  4006. "----------\n",
  4007. "LR 1e-05\n",
  4008. "train: loss: 0.000164, bce: 0.000382, dice: 1.000692\n",
  4009. "val: loss: 0.000170, bce: 0.000416, dice: 1.001296\n",
  4010. "0m 9s\n",
  4011. "\n",
  4012. "\n",
  4013. "Epoch 319/799\n",
  4014. "----------\n",
  4015. "LR 1e-05\n",
  4016. "train: loss: 0.000165, bce: 0.000386, dice: 1.000681\n",
  4017. "val: loss: 0.000169, bce: 0.000416, dice: 1.001317\n",
  4018. "saving best model\n",
  4019. "0m 9s\n",
  4020. "\n",
  4021. "\n",
  4022. "Epoch 320/799\n",
  4023. "----------\n",
  4024. "LR 1e-05\n",
  4025. "train: loss: 0.000162, bce: 0.000381, dice: 1.000698\n",
  4026. "val: loss: 0.000171, bce: 0.000415, dice: 1.001297\n",
  4027. "0m 9s\n",
  4028. "\n",
  4029. "\n",
  4030. "Epoch 321/799\n",
  4031. "----------\n",
  4032. "LR 1e-05\n",
  4033. "train: loss: 0.000163, bce: 0.000383, dice: 1.000683\n",
  4034. "val: loss: 0.000168, bce: 0.000415, dice: 1.001329\n",
  4035. "saving best model\n",
  4036. "0m 9s\n",
  4037. "\n",
  4038. "\n",
  4039. "Epoch 322/799\n",
  4040. "----------\n",
  4041. "LR 1e-05\n",
  4042. "train: loss: 0.000161, bce: 0.000380, dice: 1.000691\n",
  4043. "val: loss: 0.000168, bce: 0.000412, dice: 1.001323\n",
  4044. "0m 9s\n",
  4045. "\n",
  4046. "\n",
  4047. "Epoch 323/799\n",
  4048. "----------\n",
  4049. "LR 1e-05\n",
  4050. "train: loss: 0.000162, bce: 0.000380, dice: 1.000694\n",
  4051. "val: loss: 0.000168, bce: 0.000411, dice: 1.001316\n",
  4052. "saving best model\n",
  4053. "0m 9s\n",
  4054. "\n",
  4055. "\n",
  4056. "Epoch 324/799\n",
  4057. "----------\n",
  4058. "LR 1e-05\n",
  4059. "train: loss: 0.000161, bce: 0.000376, dice: 1.000695\n",
  4060. "val: loss: 0.000168, bce: 0.000411, dice: 1.001325\n",
  4061. "saving best model\n",
  4062. "0m 9s\n",
  4063. "\n",
  4064. "\n",
  4065. "Epoch 325/799\n",
  4066. "----------\n",
  4067. "LR 1e-05\n",
  4068. "train: loss: 0.000161, bce: 0.000377, dice: 1.000694\n",
  4069. "val: loss: 0.000168, bce: 0.000414, dice: 1.001318\n",
  4070. "saving best model\n",
  4071. "0m 9s\n",
  4072. "\n",
  4073. "\n",
  4074. "Epoch 326/799\n",
  4075. "----------\n",
  4076. "LR 1e-05\n",
  4077. "train: loss: 0.000160, bce: 0.000377, dice: 1.000688\n",
  4078. "val: loss: 0.000167, bce: 0.000410, dice: 1.001326\n",
  4079. "saving best model\n",
  4080. "0m 9s\n",
  4081. "\n",
  4082. "\n",
  4083. "Epoch 327/799\n",
  4084. "----------\n",
  4085. "LR 1e-05\n",
  4086. "train: loss: 0.000160, bce: 0.000376, dice: 1.000690\n",
  4087. "val: loss: 0.000168, bce: 0.000409, dice: 1.001290\n",
  4088. "0m 9s\n",
  4089. "\n",
  4090. "\n",
  4091. "Epoch 328/799\n",
  4092. "----------\n",
  4093. "LR 1e-05\n",
  4094. "train: loss: 0.000162, bce: 0.000377, dice: 1.000683\n",
  4095. "val: loss: 0.000170, bce: 0.000413, dice: 1.001361\n",
  4096. "0m 9s\n",
  4097. "\n",
  4098. "\n",
  4099. "Epoch 329/799\n",
  4100. "----------\n",
  4101. "LR 1e-05\n",
  4102. "train: loss: 0.000161, bce: 0.000376, dice: 1.000687\n",
  4103. "val: loss: 0.000167, bce: 0.000411, dice: 1.001315\n",
  4104. "saving best model\n",
  4105. "0m 9s\n",
  4106. "\n",
  4107. "\n",
  4108. "Epoch 330/799\n",
  4109. "----------\n",
  4110. "LR 1e-05\n",
  4111. "train: loss: 0.000160, bce: 0.000375, dice: 1.000688\n",
  4112. "val: loss: 0.000167, bce: 0.000409, dice: 1.001299\n",
  4113. "0m 9s\n",
  4114. "\n",
  4115. "\n",
  4116. "Epoch 331/799\n",
  4117. "----------\n",
  4118. "LR 1e-05\n",
  4119. "train: loss: 0.000163, bce: 0.000381, dice: 1.000703\n",
  4120. "val: loss: 0.000177, bce: 0.000417, dice: 1.001301\n",
  4121. "0m 9s\n",
  4122. "\n",
  4123. "\n",
  4124. "Epoch 332/799\n",
  4125. "----------\n",
  4126. "LR 1e-05\n",
  4127. "train: loss: 0.000162, bce: 0.000377, dice: 1.000679\n",
  4128. "val: loss: 0.000171, bce: 0.000422, dice: 1.001363\n",
  4129. "0m 9s\n",
  4130. "\n",
  4131. "\n",
  4132. "Epoch 333/799\n",
  4133. "----------\n",
  4134. "LR 1e-05\n",
  4135. "train: loss: 0.000159, bce: 0.000376, dice: 1.000687\n",
  4136. "val: loss: 0.000166, bce: 0.000407, dice: 1.001307\n",
  4137. "saving best model\n",
  4138. "0m 9s\n",
  4139. "\n",
  4140. "\n",
  4141. "Epoch 334/799\n",
  4142. "----------\n",
  4143. "LR 1e-05\n",
  4144. "train: loss: 0.000160, bce: 0.000373, dice: 1.000686\n",
  4145. "val: loss: 0.000166, bce: 0.000406, dice: 1.001319\n",
  4146. "0m 9s\n",
  4147. "\n",
  4148. "\n",
  4149. "Epoch 335/799\n",
  4150. "----------\n",
  4151. "LR 1e-05\n",
  4152. "train: loss: 0.000160, bce: 0.000375, dice: 1.000690\n",
  4153. "val: loss: 0.000171, bce: 0.000410, dice: 1.001252\n",
  4154. "0m 9s\n",
  4155. "\n",
  4156. "\n",
  4157. "Epoch 336/799\n",
  4158. "----------\n",
  4159. "LR 1e-05\n",
  4160. "train: loss: 0.000165, bce: 0.000382, dice: 1.000691\n",
  4161. "val: loss: 0.000171, bce: 0.000414, dice: 1.001203\n",
  4162. "0m 9s\n",
  4163. "\n",
  4164. "\n",
  4165. "Epoch 337/799\n",
  4166. "----------\n",
  4167. "LR 1e-05\n",
  4168. "train: loss: 0.000164, bce: 0.000382, dice: 1.000676\n",
  4169. "val: loss: 0.000176, bce: 0.000415, dice: 1.001224\n",
  4170. "0m 9s\n",
  4171. "\n",
  4172. "\n",
  4173. "Epoch 338/799\n",
  4174. "----------\n",
  4175. "LR 1e-05\n",
  4176. "train: loss: 0.000164, bce: 0.000379, dice: 1.000677\n",
  4177. "val: loss: 0.000168, bce: 0.000414, dice: 1.001272\n",
  4178. "0m 9s\n",
  4179. "\n",
  4180. "\n",
  4181. "Epoch 339/799\n",
  4182. "----------\n",
  4183. "LR 1e-05\n",
  4184. "train: loss: 0.000161, bce: 0.000379, dice: 1.000678\n",
  4185. "val: loss: 0.000167, bce: 0.000410, dice: 1.001275\n",
  4186. "0m 9s\n",
  4187. "\n",
  4188. "\n",
  4189. "Epoch 340/799\n",
  4190. "----------\n",
  4191. "LR 1e-05\n",
  4192. "train: loss: 0.000162, bce: 0.000376, dice: 1.000670\n",
  4193. "val: loss: 0.000178, bce: 0.000432, dice: 1.001372\n",
  4194. "0m 9s\n",
  4195. "\n",
  4196. "\n",
  4197. "Epoch 341/799\n",
  4198. "----------\n",
  4199. "LR 1e-05\n",
  4200. "train: loss: 0.000161, bce: 0.000376, dice: 1.000696\n",
  4201. "val: loss: 0.000165, bce: 0.000407, dice: 1.001339\n",
  4202. "saving best model\n",
  4203. "0m 9s\n",
  4204. "\n",
  4205. "\n",
  4206. "Epoch 342/799\n",
  4207. "----------\n",
  4208. "LR 1e-05\n",
  4209. "train: loss: 0.000158, bce: 0.000372, dice: 1.000691\n",
  4210. "val: loss: 0.000166, bce: 0.000404, dice: 1.001269\n",
  4211. "0m 9s\n",
  4212. "\n",
  4213. "\n",
  4214. "Epoch 343/799\n",
  4215. "----------\n",
  4216. "LR 1e-05\n",
  4217. "train: loss: 0.000159, bce: 0.000371, dice: 1.000688\n",
  4218. "val: loss: 0.000167, bce: 0.000406, dice: 1.001297\n",
  4219. "0m 9s\n",
  4220. "\n",
  4221. "\n",
  4222. "Epoch 344/799\n",
  4223. "----------\n",
  4224. "LR 1e-05\n",
  4225. "train: loss: 0.000159, bce: 0.000372, dice: 1.000677\n",
  4226. "val: loss: 0.000164, bce: 0.000408, dice: 1.001329\n",
  4227. "saving best model\n",
  4228. "0m 9s\n",
  4229. "\n",
  4230. "\n",
  4231. "Epoch 345/799\n",
  4232. "----------\n",
  4233. "LR 1e-05\n",
  4234. "train: loss: 0.000158, bce: 0.000371, dice: 1.000683\n",
  4235. "val: loss: 0.000164, bce: 0.000404, dice: 1.001314\n",
  4236. "saving best model\n",
  4237. "0m 9s\n",
  4238. "\n",
  4239. "\n",
  4240. "Epoch 346/799\n",
  4241. "----------\n",
  4242. "LR 1e-05\n",
  4243. "train: loss: 0.000158, bce: 0.000370, dice: 1.000687\n",
  4244. "val: loss: 0.000167, bce: 0.000404, dice: 1.001271\n",
  4245. "0m 9s\n",
  4246. "\n",
  4247. "\n",
  4248. "Epoch 347/799\n",
  4249. "----------\n",
  4250. "LR 1e-05\n",
  4251. "train: loss: 0.000160, bce: 0.000374, dice: 1.000675\n",
  4252. "val: loss: 0.000164, bce: 0.000403, dice: 1.001293\n",
  4253. "0m 9s\n",
  4254. "\n",
  4255. "\n",
  4256. "Epoch 348/799\n",
  4257. "----------\n",
  4258. "LR 1e-05\n",
  4259. "train: loss: 0.000158, bce: 0.000369, dice: 1.000680\n",
  4260. "val: loss: 0.000164, bce: 0.000400, dice: 1.001299\n",
  4261. "0m 9s\n",
  4262. "\n",
  4263. "\n",
  4264. "Epoch 349/799\n",
  4265. "----------\n",
  4266. "LR 1e-05\n",
  4267. "train: loss: 0.000160, bce: 0.000371, dice: 1.000679\n",
  4268. "val: loss: 0.000164, bce: 0.000403, dice: 1.001299\n",
  4269. "0m 9s\n",
  4270. "\n",
  4271. "\n",
  4272. "Epoch 350/799\n",
  4273. "----------\n",
  4274. "LR 1e-05\n",
  4275. "train: loss: 0.000159, bce: 0.000371, dice: 1.000690\n",
  4276. "val: loss: 0.000168, bce: 0.000402, dice: 1.001262\n",
  4277. "0m 9s\n",
  4278. "\n",
  4279. "\n",
  4280. "Epoch 351/799\n",
  4281. "----------\n",
  4282. "LR 1e-05\n",
  4283. "train: loss: 0.000164, bce: 0.000376, dice: 1.000694\n",
  4284. "val: loss: 0.000182, bce: 0.000418, dice: 1.001228\n",
  4285. "0m 9s\n",
  4286. "\n",
  4287. "\n",
  4288. "Epoch 352/799\n",
  4289. "----------\n",
  4290. "LR 1e-05\n",
  4291. "train: loss: 0.000167, bce: 0.000382, dice: 1.000673\n",
  4292. "val: loss: 0.000167, bce: 0.000411, dice: 1.001333\n",
  4293. "0m 9s\n",
  4294. "\n",
  4295. "\n",
  4296. "Epoch 353/799\n",
  4297. "----------\n",
  4298. "LR 1e-05\n",
  4299. "train: loss: 0.000159, bce: 0.000375, dice: 1.000681\n",
  4300. "val: loss: 0.000166, bce: 0.000411, dice: 1.001358\n",
  4301. "0m 9s\n",
  4302. "\n",
  4303. "\n",
  4304. "Epoch 354/799\n",
  4305. "----------\n",
  4306. "LR 1e-05\n",
  4307. "train: loss: 0.000160, bce: 0.000373, dice: 1.000684\n",
  4308. "val: loss: 0.000164, bce: 0.000409, dice: 1.001321\n",
  4309. "0m 9s\n",
  4310. "\n",
  4311. "\n",
  4312. "Epoch 355/799\n",
  4313. "----------\n",
  4314. "LR 1e-05\n",
  4315. "train: loss: 0.000159, bce: 0.000371, dice: 1.000680\n",
  4316. "val: loss: 0.000163, bce: 0.000400, dice: 1.001290\n",
  4317. "saving best model\n",
  4318. "0m 9s\n",
  4319. "\n",
  4320. "\n",
  4321. "Epoch 356/799\n",
  4322. "----------\n",
  4323. "LR 1e-05\n",
  4324. "train: loss: 0.000157, bce: 0.000369, dice: 1.000684\n",
  4325. "val: loss: 0.000162, bce: 0.000401, dice: 1.001305\n",
  4326. "saving best model\n",
  4327. "0m 9s\n",
  4328. "\n",
  4329. "\n",
  4330. "Epoch 357/799\n",
  4331. "----------\n",
  4332. "LR 1e-05\n",
  4333. "train: loss: 0.000156, bce: 0.000366, dice: 1.000676\n",
  4334. "val: loss: 0.000162, bce: 0.000399, dice: 1.001283\n",
  4335. "saving best model\n",
  4336. "0m 9s\n",
  4337. "\n",
  4338. "\n",
  4339. "Epoch 358/799\n",
  4340. "----------\n",
  4341. "LR 1e-05\n",
  4342. "train: loss: 0.000156, bce: 0.000365, dice: 1.000674\n",
  4343. "val: loss: 0.000161, bce: 0.000398, dice: 1.001295\n",
  4344. "saving best model\n",
  4345. "0m 9s\n",
  4346. "\n",
  4347. "\n",
  4348. "Epoch 359/799\n",
  4349. "----------\n",
  4350. "LR 1e-05\n",
  4351. "train: loss: 0.000155, bce: 0.000362, dice: 1.000672\n",
  4352. "val: loss: 0.000161, bce: 0.000400, dice: 1.001298\n",
  4353. "0m 9s\n",
  4354. "\n",
  4355. "\n",
  4356. "Epoch 360/799\n",
  4357. "----------\n",
  4358. "LR 1e-05\n",
  4359. "train: loss: 0.000156, bce: 0.000364, dice: 1.000677\n",
  4360. "val: loss: 0.000161, bce: 0.000397, dice: 1.001287\n",
  4361. "saving best model\n",
  4362. "0m 9s\n",
  4363. "\n",
  4364. "\n",
  4365. "Epoch 361/799\n",
  4366. "----------\n",
  4367. "LR 1e-05\n",
  4368. "train: loss: 0.000156, bce: 0.000364, dice: 1.000677\n",
  4369. "val: loss: 0.000161, bce: 0.000395, dice: 1.001278\n",
  4370. "0m 9s\n",
  4371. "\n",
  4372. "\n",
  4373. "Epoch 362/799\n",
  4374. "----------\n",
  4375. "LR 1e-05\n",
  4376. "train: loss: 0.000157, bce: 0.000363, dice: 1.000685\n",
  4377. "val: loss: 0.000164, bce: 0.000396, dice: 1.001232\n",
  4378. "0m 9s\n",
  4379. "\n",
  4380. "\n",
  4381. "Epoch 363/799\n",
  4382. "----------\n",
  4383. "LR 1e-05\n",
  4384. "train: loss: 0.000163, bce: 0.000373, dice: 1.000674\n",
  4385. "val: loss: 0.000170, bce: 0.000405, dice: 1.001233\n",
  4386. "0m 9s\n",
  4387. "\n",
  4388. "\n",
  4389. "Epoch 364/799\n",
  4390. "----------\n",
  4391. "LR 1e-05\n",
  4392. "train: loss: 0.000158, bce: 0.000367, dice: 1.000678\n",
  4393. "val: loss: 0.000164, bce: 0.000400, dice: 1.001255\n",
  4394. "0m 9s\n",
  4395. "\n",
  4396. "\n",
  4397. "Epoch 365/799\n",
  4398. "----------\n",
  4399. "LR 1e-05\n",
  4400. "train: loss: 0.000168, bce: 0.000382, dice: 1.000676\n",
  4401. "val: loss: 0.000165, bce: 0.000406, dice: 1.001231\n",
  4402. "0m 9s\n",
  4403. "\n",
  4404. "\n",
  4405. "Epoch 366/799\n",
  4406. "----------\n",
  4407. "LR 1e-05\n",
  4408. "train: loss: 0.000158, bce: 0.000369, dice: 1.000673\n",
  4409. "val: loss: 0.000164, bce: 0.000401, dice: 1.001231\n",
  4410. "0m 9s\n",
  4411. "\n",
  4412. "\n",
  4413. "Epoch 367/799\n",
  4414. "----------\n",
  4415. "LR 1e-05\n",
  4416. "train: loss: 0.000158, bce: 0.000370, dice: 1.000671\n",
  4417. "val: loss: 0.000162, bce: 0.000400, dice: 1.001233\n",
  4418. "0m 9s\n",
  4419. "\n",
  4420. "\n",
  4421. "Epoch 368/799\n",
  4422. "----------\n",
  4423. "LR 1e-05\n",
  4424. "train: loss: 0.000159, bce: 0.000369, dice: 1.000677\n",
  4425. "val: loss: 0.000162, bce: 0.000395, dice: 1.001240\n",
  4426. "0m 9s\n",
  4427. "\n",
  4428. "\n",
  4429. "Epoch 369/799\n",
  4430. "----------\n",
  4431. "LR 1e-05\n",
  4432. "train: loss: 0.000159, bce: 0.000366, dice: 1.000690\n",
  4433. "val: loss: 0.000171, bce: 0.000399, dice: 1.001226\n",
  4434. "0m 9s\n",
  4435. "\n",
  4436. "\n",
  4437. "Epoch 370/799\n",
  4438. "----------\n",
  4439. "LR 1e-05\n",
  4440. "train: loss: 0.000158, bce: 0.000366, dice: 1.000674\n",
  4441. "val: loss: 0.000162, bce: 0.000394, dice: 1.001267\n",
  4442. "0m 9s\n",
  4443. "\n",
  4444. "\n",
  4445. "Epoch 371/799\n",
  4446. "----------\n",
  4447. "LR 1e-05\n",
  4448. "train: loss: 0.000156, bce: 0.000362, dice: 1.000674\n",
  4449. "val: loss: 0.000162, bce: 0.000396, dice: 1.001246\n",
  4450. "0m 9s\n",
  4451. "\n",
  4452. "\n",
  4453. "Epoch 372/799\n",
  4454. "----------\n",
  4455. "LR 1e-05\n",
  4456. "train: loss: 0.000154, bce: 0.000360, dice: 1.000665\n",
  4457. "val: loss: 0.000159, bce: 0.000396, dice: 1.001277\n",
  4458. "saving best model\n",
  4459. "0m 9s\n",
  4460. "\n",
  4461. "\n",
  4462. "Epoch 373/799\n",
  4463. "----------\n",
  4464. "LR 1e-05\n",
  4465. "train: loss: 0.000154, bce: 0.000361, dice: 1.000673\n",
  4466. "val: loss: 0.000159, bce: 0.000393, dice: 1.001285\n",
  4467. "saving best model\n",
  4468. "0m 9s\n",
  4469. "\n",
  4470. "\n",
  4471. "Epoch 374/799\n",
  4472. "----------\n",
  4473. "LR 1e-05\n",
  4474. "train: loss: 0.000154, bce: 0.000358, dice: 1.000666\n",
  4475. "val: loss: 0.000159, bce: 0.000392, dice: 1.001280\n",
  4476. "saving best model\n",
  4477. "0m 9s\n",
  4478. "\n",
  4479. "\n",
  4480. "Epoch 375/799\n",
  4481. "----------\n",
  4482. "LR 1e-05\n",
  4483. "train: loss: 0.000153, bce: 0.000358, dice: 1.000672\n",
  4484. "val: loss: 0.000159, bce: 0.000392, dice: 1.001276\n",
  4485. "saving best model\n",
  4486. "0m 9s\n",
  4487. "\n",
  4488. "\n",
  4489. "Epoch 376/799\n",
  4490. "----------\n",
  4491. "LR 1e-05\n",
  4492. "train: loss: 0.000155, bce: 0.000358, dice: 1.000668\n",
  4493. "val: loss: 0.000158, bce: 0.000393, dice: 1.001289\n",
  4494. "saving best model\n",
  4495. "0m 9s\n",
  4496. "\n",
  4497. "\n",
  4498. "Epoch 377/799\n",
  4499. "----------\n",
  4500. "LR 1e-05\n",
  4501. "train: loss: 0.000154, bce: 0.000361, dice: 1.000666\n",
  4502. "val: loss: 0.000159, bce: 0.000391, dice: 1.001283\n",
  4503. "0m 9s\n",
  4504. "\n",
  4505. "\n",
  4506. "Epoch 378/799\n",
  4507. "----------\n",
  4508. "LR 1e-05\n",
  4509. "train: loss: 0.000153, bce: 0.000357, dice: 1.000672\n",
  4510. "val: loss: 0.000158, bce: 0.000389, dice: 1.001262\n",
  4511. "saving best model\n",
  4512. "0m 9s\n",
  4513. "\n",
  4514. "\n",
  4515. "Epoch 379/799\n",
  4516. "----------\n",
  4517. "LR 1e-05\n",
  4518. "train: loss: 0.000153, bce: 0.000356, dice: 1.000670\n",
  4519. "val: loss: 0.000158, bce: 0.000388, dice: 1.001263\n",
  4520. "saving best model\n",
  4521. "0m 9s\n",
  4522. "\n",
  4523. "\n",
  4524. "Epoch 380/799\n",
  4525. "----------\n",
  4526. "LR 1e-05\n",
  4527. "train: loss: 0.000154, bce: 0.000357, dice: 1.000668\n",
  4528. "val: loss: 0.000163, bce: 0.000389, dice: 1.001220\n",
  4529. "0m 9s\n",
  4530. "\n",
  4531. "\n",
  4532. "Epoch 381/799\n",
  4533. "----------\n",
  4534. "LR 1e-05\n",
  4535. "train: loss: 0.000159, bce: 0.000365, dice: 1.000657\n",
  4536. "val: loss: 0.000158, bce: 0.000392, dice: 1.001263\n",
  4537. "0m 9s\n",
  4538. "\n",
  4539. "\n",
  4540. "Epoch 382/799\n",
  4541. "----------\n",
  4542. "LR 1e-05\n",
  4543. "train: loss: 0.000153, bce: 0.000356, dice: 1.000662\n",
  4544. "val: loss: 0.000158, bce: 0.000390, dice: 1.001282\n",
  4545. "0m 9s\n",
  4546. "\n",
  4547. "\n",
  4548. "Epoch 383/799\n",
  4549. "----------\n",
  4550. "LR 1e-05\n",
  4551. "train: loss: 0.000152, bce: 0.000354, dice: 1.000666\n",
  4552. "val: loss: 0.000157, bce: 0.000389, dice: 1.001270\n",
  4553. "saving best model\n",
  4554. "0m 9s\n",
  4555. "\n",
  4556. "\n",
  4557. "Epoch 384/799\n",
  4558. "----------\n",
  4559. "LR 1e-05\n",
  4560. "train: loss: 0.000152, bce: 0.000353, dice: 1.000663\n",
  4561. "val: loss: 0.000158, bce: 0.000391, dice: 1.001292\n",
  4562. "0m 9s\n",
  4563. "\n",
  4564. "\n",
  4565. "Epoch 385/799\n",
  4566. "----------\n",
  4567. "LR 1e-05\n",
  4568. "train: loss: 0.000153, bce: 0.000355, dice: 1.000662\n",
  4569. "val: loss: 0.000163, bce: 0.000400, dice: 1.001304\n",
  4570. "0m 9s\n",
  4571. "\n",
  4572. "\n",
  4573. "Epoch 386/799\n",
  4574. "----------\n",
  4575. "LR 1e-05\n",
  4576. "train: loss: 0.000156, bce: 0.000357, dice: 1.000653\n",
  4577. "val: loss: 0.000178, bce: 0.000420, dice: 1.001368\n",
  4578. "0m 9s\n",
  4579. "\n",
  4580. "\n",
  4581. "Epoch 387/799\n",
  4582. "----------\n",
  4583. "LR 1e-05\n",
  4584. "train: loss: 0.000173, bce: 0.000386, dice: 1.000657\n",
  4585. "val: loss: 0.000173, bce: 0.000426, dice: 1.001288\n",
  4586. "0m 9s\n",
  4587. "\n",
  4588. "\n",
  4589. "Epoch 388/799\n",
  4590. "----------\n",
  4591. "LR 1e-05\n",
  4592. "train: loss: 0.000157, bce: 0.000369, dice: 1.000667\n",
  4593. "val: loss: 0.000162, bce: 0.000394, dice: 1.001193\n",
  4594. "0m 9s\n",
  4595. "\n",
  4596. "\n",
  4597. "Epoch 389/799\n",
  4598. "----------\n",
  4599. "LR 1e-05\n",
  4600. "train: loss: 0.000161, bce: 0.000370, dice: 1.000645\n",
  4601. "val: loss: 0.000159, bce: 0.000391, dice: 1.001225\n",
  4602. "0m 9s\n",
  4603. "\n",
  4604. "\n",
  4605. "Epoch 390/799\n",
  4606. "----------\n",
  4607. "LR 1e-05\n",
  4608. "train: loss: 0.000154, bce: 0.000358, dice: 1.000653\n",
  4609. "val: loss: 0.000157, bce: 0.000390, dice: 1.001255\n",
  4610. "saving best model\n",
  4611. "0m 9s\n",
  4612. "\n",
  4613. "\n",
  4614. "Epoch 391/799\n",
  4615. "----------\n",
  4616. "LR 1e-05\n",
  4617. "train: loss: 0.000153, bce: 0.000355, dice: 1.000660\n",
  4618. "val: loss: 0.000156, bce: 0.000388, dice: 1.001250\n",
  4619. "saving best model\n",
  4620. "0m 9s\n",
  4621. "\n",
  4622. "\n",
  4623. "Epoch 392/799\n",
  4624. "----------\n",
  4625. "LR 1e-05\n",
  4626. "train: loss: 0.000152, bce: 0.000354, dice: 1.000659\n",
  4627. "val: loss: 0.000157, bce: 0.000390, dice: 1.001275\n",
  4628. "0m 9s\n",
  4629. "\n",
  4630. "\n",
  4631. "Epoch 393/799\n",
  4632. "----------\n",
  4633. "LR 1e-05\n",
  4634. "train: loss: 0.000152, bce: 0.000354, dice: 1.000658\n",
  4635. "val: loss: 0.000156, bce: 0.000387, dice: 1.001252\n",
  4636. "saving best model\n",
  4637. "0m 9s\n",
  4638. "\n",
  4639. "\n",
  4640. "Epoch 394/799\n",
  4641. "----------\n",
  4642. "LR 1e-05\n",
  4643. "train: loss: 0.000151, bce: 0.000352, dice: 1.000659\n",
  4644. "val: loss: 0.000156, bce: 0.000386, dice: 1.001271\n",
  4645. "0m 9s\n",
  4646. "\n",
  4647. "\n",
  4648. "Epoch 395/799\n",
  4649. "----------\n",
  4650. "LR 1e-05\n",
  4651. "train: loss: 0.000153, bce: 0.000353, dice: 1.000660\n",
  4652. "val: loss: 0.000156, bce: 0.000385, dice: 1.001266\n",
  4653. "saving best model\n",
  4654. "0m 9s\n",
  4655. "\n",
  4656. "\n",
  4657. "Epoch 396/799\n",
  4658. "----------\n",
  4659. "LR 1e-05\n",
  4660. "train: loss: 0.000151, bce: 0.000352, dice: 1.000663\n",
  4661. "val: loss: 0.000155, bce: 0.000382, dice: 1.001231\n",
  4662. "saving best model\n",
  4663. "0m 9s\n",
  4664. "\n",
  4665. "\n",
  4666. "Epoch 397/799\n",
  4667. "----------\n",
  4668. "LR 1e-05\n",
  4669. "train: loss: 0.000151, bce: 0.000351, dice: 1.000657\n",
  4670. "val: loss: 0.000155, bce: 0.000381, dice: 1.001248\n",
  4671. "saving best model\n",
  4672. "0m 9s\n",
  4673. "\n",
  4674. "\n",
  4675. "Epoch 398/799\n",
  4676. "----------\n",
  4677. "LR 1e-05\n",
  4678. "train: loss: 0.000151, bce: 0.000350, dice: 1.000661\n",
  4679. "val: loss: 0.000158, bce: 0.000381, dice: 1.001202\n",
  4680. "0m 9s\n",
  4681. "\n",
  4682. "\n",
  4683. "Epoch 399/799\n",
  4684. "----------\n",
  4685. "LR 1.0000000000000002e-06\n",
  4686. "train: loss: 0.000151, bce: 0.000348, dice: 1.000645\n",
  4687. "val: loss: 0.000156, bce: 0.000381, dice: 1.001221\n",
  4688. "0m 9s\n",
  4689. "\n",
  4690. "\n",
  4691. "Epoch 400/799\n",
  4692. "----------\n",
  4693. "LR 1.0000000000000002e-06\n",
  4694. "train: loss: 0.000150, bce: 0.000348, dice: 1.000651\n",
  4695. "val: loss: 0.000155, bce: 0.000381, dice: 1.001230\n",
  4696. "saving best model\n",
  4697. "0m 9s\n",
  4698. "\n",
  4699. "\n",
  4700. "Epoch 401/799\n",
  4701. "----------\n",
  4702. "LR 1.0000000000000002e-06\n",
  4703. "train: loss: 0.000150, bce: 0.000348, dice: 1.000655\n",
  4704. "val: loss: 0.000155, bce: 0.000381, dice: 1.001233\n",
  4705. "saving best model\n",
  4706. "0m 9s\n",
  4707. "\n",
  4708. "\n",
  4709. "Epoch 402/799\n",
  4710. "----------\n",
  4711. "LR 1.0000000000000002e-06\n",
  4712. "train: loss: 0.000150, bce: 0.000348, dice: 1.000656\n",
  4713. "val: loss: 0.000155, bce: 0.000381, dice: 1.001234\n",
  4714. "saving best model\n",
  4715. "0m 9s\n",
  4716. "\n",
  4717. "\n",
  4718. "Epoch 403/799\n",
  4719. "----------\n",
  4720. "LR 1.0000000000000002e-06\n",
  4721. "train: loss: 0.000149, bce: 0.000348, dice: 1.000656\n",
  4722. "val: loss: 0.000155, bce: 0.000381, dice: 1.001236\n",
  4723. "saving best model\n",
  4724. "0m 9s\n",
  4725. "\n",
  4726. "\n",
  4727. "Epoch 404/799\n",
  4728. "----------\n",
  4729. "LR 1.0000000000000002e-06\n",
  4730. "train: loss: 0.000149, bce: 0.000348, dice: 1.000656\n",
  4731. "val: loss: 0.000155, bce: 0.000381, dice: 1.001238\n",
  4732. "saving best model\n",
  4733. "0m 9s\n",
  4734. "\n",
  4735. "\n",
  4736. "Epoch 405/799\n",
  4737. "----------\n",
  4738. "LR 1.0000000000000002e-06\n",
  4739. "train: loss: 0.000149, bce: 0.000348, dice: 1.000657\n",
  4740. "val: loss: 0.000155, bce: 0.000381, dice: 1.001238\n",
  4741. "saving best model\n",
  4742. "0m 9s\n",
  4743. "\n",
  4744. "\n",
  4745. "Epoch 406/799\n",
  4746. "----------\n",
  4747. "LR 1.0000000000000002e-06\n",
  4748. "train: loss: 0.000149, bce: 0.000348, dice: 1.000658\n",
  4749. "val: loss: 0.000155, bce: 0.000381, dice: 1.001238\n",
  4750. "saving best model\n",
  4751. "0m 9s\n",
  4752. "\n",
  4753. "\n",
  4754. "Epoch 407/799\n",
  4755. "----------\n",
  4756. "LR 1.0000000000000002e-06\n",
  4757. "train: loss: 0.000149, bce: 0.000348, dice: 1.000657\n",
  4758. "val: loss: 0.000154, bce: 0.000380, dice: 1.001239\n",
  4759. "saving best model\n",
  4760. "0m 9s\n",
  4761. "\n",
  4762. "\n",
  4763. "Epoch 408/799\n",
  4764. "----------\n",
  4765. "LR 1.0000000000000002e-06\n",
  4766. "train: loss: 0.000149, bce: 0.000348, dice: 1.000657\n",
  4767. "val: loss: 0.000154, bce: 0.000380, dice: 1.001239\n",
  4768. "saving best model\n",
  4769. "0m 9s\n",
  4770. "\n",
  4771. "\n",
  4772. "Epoch 409/799\n",
  4773. "----------\n",
  4774. "LR 1.0000000000000002e-06\n",
  4775. "train: loss: 0.000149, bce: 0.000347, dice: 1.000658\n",
  4776. "val: loss: 0.000154, bce: 0.000380, dice: 1.001239\n",
  4777. "saving best model\n",
  4778. "0m 9s\n",
  4779. "\n",
  4780. "\n",
  4781. "Epoch 410/799\n",
  4782. "----------\n",
  4783. "LR 1.0000000000000002e-06\n",
  4784. "train: loss: 0.000149, bce: 0.000347, dice: 1.000658\n",
  4785. "val: loss: 0.000154, bce: 0.000380, dice: 1.001239\n",
  4786. "saving best model\n",
  4787. "0m 9s\n",
  4788. "\n",
  4789. "\n",
  4790. "Epoch 411/799\n",
  4791. "----------\n",
  4792. "LR 1.0000000000000002e-06\n",
  4793. "train: loss: 0.000149, bce: 0.000347, dice: 1.000658\n",
  4794. "val: loss: 0.000154, bce: 0.000380, dice: 1.001239\n",
  4795. "saving best model\n",
  4796. "0m 9s\n",
  4797. "\n",
  4798. "\n",
  4799. "Epoch 412/799\n",
  4800. "----------\n",
  4801. "LR 1.0000000000000002e-06\n",
  4802. "train: loss: 0.000149, bce: 0.000347, dice: 1.000657\n",
  4803. "val: loss: 0.000154, bce: 0.000380, dice: 1.001240\n",
  4804. "saving best model\n",
  4805. "0m 9s\n",
  4806. "\n",
  4807. "\n",
  4808. "Epoch 413/799\n",
  4809. "----------\n",
  4810. "LR 1.0000000000000002e-06\n",
  4811. "train: loss: 0.000149, bce: 0.000347, dice: 1.000658\n",
  4812. "val: loss: 0.000154, bce: 0.000380, dice: 1.001240\n",
  4813. "saving best model\n",
  4814. "0m 9s\n",
  4815. "\n",
  4816. "\n",
  4817. "Epoch 414/799\n",
  4818. "----------\n",
  4819. "LR 1.0000000000000002e-06\n",
  4820. "train: loss: 0.000149, bce: 0.000347, dice: 1.000658\n",
  4821. "val: loss: 0.000154, bce: 0.000380, dice: 1.001239\n",
  4822. "saving best model\n",
  4823. "0m 9s\n",
  4824. "\n",
  4825. "\n",
  4826. "Epoch 415/799\n",
  4827. "----------\n",
  4828. "LR 1.0000000000000002e-06\n",
  4829. "train: loss: 0.000149, bce: 0.000347, dice: 1.000658\n",
  4830. "val: loss: 0.000154, bce: 0.000380, dice: 1.001239\n",
  4831. "saving best model\n",
  4832. "0m 9s\n",
  4833. "\n",
  4834. "\n",
  4835. "Epoch 416/799\n",
  4836. "----------\n",
  4837. "LR 1.0000000000000002e-06\n",
  4838. "train: loss: 0.000149, bce: 0.000347, dice: 1.000657\n",
  4839. "val: loss: 0.000154, bce: 0.000380, dice: 1.001240\n",
  4840. "saving best model\n",
  4841. "0m 9s\n",
  4842. "\n",
  4843. "\n",
  4844. "Epoch 417/799\n",
  4845. "----------\n",
  4846. "LR 1.0000000000000002e-06\n",
  4847. "train: loss: 0.000149, bce: 0.000347, dice: 1.000657\n",
  4848. "val: loss: 0.000154, bce: 0.000380, dice: 1.001240\n",
  4849. "saving best model\n",
  4850. "0m 9s\n",
  4851. "\n",
  4852. "\n",
  4853. "Epoch 418/799\n",
  4854. "----------\n",
  4855. "LR 1.0000000000000002e-06\n",
  4856. "train: loss: 0.000149, bce: 0.000347, dice: 1.000658\n",
  4857. "val: loss: 0.000154, bce: 0.000379, dice: 1.001239\n",
  4858. "saving best model\n",
  4859. "0m 9s\n",
  4860. "\n",
  4861. "\n",
  4862. "Epoch 419/799\n",
  4863. "----------\n",
  4864. "LR 1.0000000000000002e-06\n",
  4865. "train: loss: 0.000149, bce: 0.000347, dice: 1.000657\n",
  4866. "val: loss: 0.000154, bce: 0.000379, dice: 1.001239\n",
  4867. "saving best model\n",
  4868. "0m 9s\n",
  4869. "\n",
  4870. "\n",
  4871. "Epoch 420/799\n",
  4872. "----------\n",
  4873. "LR 1.0000000000000002e-06\n",
  4874. "train: loss: 0.000149, bce: 0.000346, dice: 1.000657\n",
  4875. "val: loss: 0.000154, bce: 0.000379, dice: 1.001239\n",
  4876. "saving best model\n",
  4877. "0m 9s\n",
  4878. "\n",
  4879. "\n",
  4880. "Epoch 421/799\n",
  4881. "----------\n",
  4882. "LR 1.0000000000000002e-06\n",
  4883. "train: loss: 0.000149, bce: 0.000346, dice: 1.000657\n",
  4884. "val: loss: 0.000154, bce: 0.000379, dice: 1.001240\n",
  4885. "saving best model\n",
  4886. "0m 9s\n",
  4887. "\n",
  4888. "\n",
  4889. "Epoch 422/799\n",
  4890. "----------\n",
  4891. "LR 1.0000000000000002e-06\n",
  4892. "train: loss: 0.000149, bce: 0.000347, dice: 1.000658\n",
  4893. "val: loss: 0.000154, bce: 0.000379, dice: 1.001238\n",
  4894. "saving best model\n",
  4895. "0m 9s\n",
  4896. "\n",
  4897. "\n",
  4898. "Epoch 423/799\n",
  4899. "----------\n",
  4900. "LR 1.0000000000000002e-06\n",
  4901. "train: loss: 0.000149, bce: 0.000346, dice: 1.000657\n",
  4902. "val: loss: 0.000154, bce: 0.000379, dice: 1.001238\n",
  4903. "saving best model\n",
  4904. "0m 9s\n",
  4905. "\n",
  4906. "\n",
  4907. "Epoch 424/799\n",
  4908. "----------\n",
  4909. "LR 1.0000000000000002e-06\n",
  4910. "train: loss: 0.000149, bce: 0.000346, dice: 1.000657\n",
  4911. "val: loss: 0.000154, bce: 0.000379, dice: 1.001238\n",
  4912. "saving best model\n",
  4913. "0m 9s\n",
  4914. "\n",
  4915. "\n",
  4916. "Epoch 425/799\n",
  4917. "----------\n",
  4918. "LR 1.0000000000000002e-06\n",
  4919. "train: loss: 0.000149, bce: 0.000346, dice: 1.000657\n",
  4920. "val: loss: 0.000154, bce: 0.000379, dice: 1.001237\n",
  4921. "saving best model\n",
  4922. "0m 9s\n",
  4923. "\n",
  4924. "\n",
  4925. "Epoch 426/799\n",
  4926. "----------\n",
  4927. "LR 1.0000000000000002e-06\n",
  4928. "train: loss: 0.000149, bce: 0.000346, dice: 1.000657\n",
  4929. "val: loss: 0.000154, bce: 0.000378, dice: 1.001237\n",
  4930. "saving best model\n",
  4931. "0m 9s\n",
  4932. "\n",
  4933. "\n",
  4934. "Epoch 427/799\n",
  4935. "----------\n",
  4936. "LR 1.0000000000000002e-06\n",
  4937. "train: loss: 0.000149, bce: 0.000346, dice: 1.000657\n",
  4938. "val: loss: 0.000154, bce: 0.000378, dice: 1.001238\n",
  4939. "saving best model\n",
  4940. "0m 9s\n",
  4941. "\n",
  4942. "\n",
  4943. "Epoch 428/799\n",
  4944. "----------\n",
  4945. "LR 1.0000000000000002e-06\n",
  4946. "train: loss: 0.000149, bce: 0.000346, dice: 1.000657\n",
  4947. "val: loss: 0.000154, bce: 0.000378, dice: 1.001236\n",
  4948. "saving best model\n",
  4949. "0m 9s\n",
  4950. "\n",
  4951. "\n",
  4952. "Epoch 429/799\n",
  4953. "----------\n",
  4954. "LR 1.0000000000000002e-06\n",
  4955. "train: loss: 0.000149, bce: 0.000346, dice: 1.000657\n",
  4956. "val: loss: 0.000154, bce: 0.000378, dice: 1.001237\n",
  4957. "saving best model\n",
  4958. "0m 9s\n",
  4959. "\n",
  4960. "\n",
  4961. "Epoch 430/799\n",
  4962. "----------\n",
  4963. "LR 1.0000000000000002e-06\n",
  4964. "train: loss: 0.000149, bce: 0.000346, dice: 1.000657\n",
  4965. "val: loss: 0.000154, bce: 0.000378, dice: 1.001236\n",
  4966. "saving best model\n",
  4967. "0m 9s\n",
  4968. "\n",
  4969. "\n",
  4970. "Epoch 431/799\n",
  4971. "----------\n",
  4972. "LR 1.0000000000000002e-06\n",
  4973. "train: loss: 0.000149, bce: 0.000345, dice: 1.000656\n",
  4974. "val: loss: 0.000154, bce: 0.000378, dice: 1.001238\n",
  4975. "saving best model\n",
  4976. "0m 9s\n",
  4977. "\n",
  4978. "\n",
  4979. "Epoch 432/799\n",
  4980. "----------\n",
  4981. "LR 1.0000000000000002e-06\n",
  4982. "train: loss: 0.000149, bce: 0.000346, dice: 1.000657\n",
  4983. "val: loss: 0.000154, bce: 0.000378, dice: 1.001237\n",
  4984. "saving best model\n",
  4985. "0m 9s\n",
  4986. "\n",
  4987. "\n",
  4988. "Epoch 433/799\n",
  4989. "----------\n",
  4990. "LR 1.0000000000000002e-06\n",
  4991. "train: loss: 0.000149, bce: 0.000346, dice: 1.000657\n",
  4992. "val: loss: 0.000154, bce: 0.000378, dice: 1.001235\n",
  4993. "saving best model\n",
  4994. "0m 9s\n",
  4995. "\n",
  4996. "\n",
  4997. "Epoch 434/799\n",
  4998. "----------\n",
  4999. "LR 1.0000000000000002e-06\n",
  5000. "train: loss: 0.000149, bce: 0.000346, dice: 1.000656\n",
  5001. "val: loss: 0.000154, bce: 0.000378, dice: 1.001235\n",
  5002. "saving best model\n",
  5003. "0m 9s\n",
  5004. "\n",
  5005. "\n",
  5006. "Epoch 435/799\n",
  5007. "----------\n",
  5008. "LR 1.0000000000000002e-06\n",
  5009. "train: loss: 0.000149, bce: 0.000345, dice: 1.000655\n",
  5010. "val: loss: 0.000154, bce: 0.000378, dice: 1.001236\n",
  5011. "saving best model\n",
  5012. "0m 9s\n",
  5013. "\n",
  5014. "\n",
  5015. "Epoch 436/799\n",
  5016. "----------\n",
  5017. "LR 1.0000000000000002e-06\n",
  5018. "train: loss: 0.000149, bce: 0.000345, dice: 1.000656\n",
  5019. "val: loss: 0.000154, bce: 0.000377, dice: 1.001234\n",
  5020. "saving best model\n",
  5021. "0m 9s\n",
  5022. "\n",
  5023. "\n",
  5024. "Epoch 437/799\n",
  5025. "----------\n",
  5026. "LR 1.0000000000000002e-06\n",
  5027. "train: loss: 0.000149, bce: 0.000345, dice: 1.000656\n",
  5028. "val: loss: 0.000154, bce: 0.000377, dice: 1.001235\n",
  5029. "saving best model\n",
  5030. "0m 9s\n",
  5031. "\n",
  5032. "\n",
  5033. "Epoch 438/799\n",
  5034. "----------\n",
  5035. "LR 1.0000000000000002e-06\n",
  5036. "train: loss: 0.000149, bce: 0.000345, dice: 1.000657\n",
  5037. "val: loss: 0.000154, bce: 0.000377, dice: 1.001233\n",
  5038. "saving best model\n",
  5039. "0m 9s\n",
  5040. "\n",
  5041. "\n",
  5042. "Epoch 439/799\n",
  5043. "----------\n",
  5044. "LR 1.0000000000000002e-06\n",
  5045. "train: loss: 0.000149, bce: 0.000345, dice: 1.000656\n",
  5046. "val: loss: 0.000154, bce: 0.000377, dice: 1.001234\n",
  5047. "saving best model\n",
  5048. "0m 9s\n",
  5049. "\n",
  5050. "\n",
  5051. "Epoch 440/799\n",
  5052. "----------\n",
  5053. "LR 1.0000000000000002e-06\n",
  5054. "train: loss: 0.000149, bce: 0.000345, dice: 1.000656\n",
  5055. "val: loss: 0.000154, bce: 0.000377, dice: 1.001233\n",
  5056. "saving best model\n",
  5057. "0m 9s\n",
  5058. "\n",
  5059. "\n",
  5060. "Epoch 441/799\n",
  5061. "----------\n",
  5062. "LR 1.0000000000000002e-06\n",
  5063. "train: loss: 0.000149, bce: 0.000345, dice: 1.000655\n",
  5064. "val: loss: 0.000154, bce: 0.000377, dice: 1.001234\n",
  5065. "saving best model\n",
  5066. "0m 9s\n",
  5067. "\n",
  5068. "\n",
  5069. "Epoch 442/799\n",
  5070. "----------\n",
  5071. "LR 1.0000000000000002e-06\n",
  5072. "train: loss: 0.000149, bce: 0.000345, dice: 1.000655\n",
  5073. "val: loss: 0.000154, bce: 0.000377, dice: 1.001234\n",
  5074. "saving best model\n",
  5075. "0m 9s\n",
  5076. "\n",
  5077. "\n",
  5078. "Epoch 443/799\n",
  5079. "----------\n",
  5080. "LR 1.0000000000000002e-06\n",
  5081. "train: loss: 0.000149, bce: 0.000345, dice: 1.000656\n",
  5082. "val: loss: 0.000154, bce: 0.000377, dice: 1.001233\n",
  5083. "saving best model\n",
  5084. "0m 9s\n",
  5085. "\n",
  5086. "\n",
  5087. "Epoch 444/799\n",
  5088. "----------\n",
  5089. "LR 1.0000000000000002e-06\n",
  5090. "train: loss: 0.000149, bce: 0.000344, dice: 1.000655\n",
  5091. "val: loss: 0.000154, bce: 0.000377, dice: 1.001234\n",
  5092. "saving best model\n",
  5093. "0m 9s\n",
  5094. "\n",
  5095. "\n",
  5096. "Epoch 445/799\n",
  5097. "----------\n",
  5098. "LR 1.0000000000000002e-06\n",
  5099. "train: loss: 0.000149, bce: 0.000345, dice: 1.000655\n",
  5100. "val: loss: 0.000154, bce: 0.000377, dice: 1.001234\n",
  5101. "saving best model\n",
  5102. "0m 9s\n",
  5103. "\n",
  5104. "\n",
  5105. "Epoch 446/799\n",
  5106. "----------\n",
  5107. "LR 1.0000000000000002e-06\n",
  5108. "train: loss: 0.000149, bce: 0.000344, dice: 1.000655\n",
  5109. "val: loss: 0.000153, bce: 0.000376, dice: 1.001233\n",
  5110. "saving best model\n",
  5111. "0m 9s\n",
  5112. "\n",
  5113. "\n",
  5114. "Epoch 447/799\n",
  5115. "----------\n",
  5116. "LR 1.0000000000000002e-06\n",
  5117. "train: loss: 0.000149, bce: 0.000344, dice: 1.000655\n",
  5118. "val: loss: 0.000153, bce: 0.000376, dice: 1.001232\n",
  5119. "saving best model\n",
  5120. "0m 9s\n",
  5121. "\n",
  5122. "\n",
  5123. "Epoch 448/799\n",
  5124. "----------\n",
  5125. "LR 1.0000000000000002e-06\n",
  5126. "train: loss: 0.000149, bce: 0.000344, dice: 1.000656\n",
  5127. "val: loss: 0.000153, bce: 0.000376, dice: 1.001229\n",
  5128. "saving best model\n",
  5129. "0m 9s\n",
  5130. "\n",
  5131. "\n",
  5132. "Epoch 449/799\n",
  5133. "----------\n",
  5134. "LR 1.0000000000000002e-06\n",
  5135. "train: loss: 0.000148, bce: 0.000344, dice: 1.000654\n",
  5136. "val: loss: 0.000153, bce: 0.000376, dice: 1.001230\n",
  5137. "saving best model\n",
  5138. "0m 9s\n",
  5139. "\n",
  5140. "\n",
  5141. "Epoch 450/799\n",
  5142. "----------\n",
  5143. "LR 1.0000000000000002e-06\n",
  5144. "train: loss: 0.000148, bce: 0.000344, dice: 1.000655\n",
  5145. "val: loss: 0.000153, bce: 0.000376, dice: 1.001229\n",
  5146. "saving best model\n",
  5147. "0m 9s\n",
  5148. "\n",
  5149. "\n",
  5150. "Epoch 451/799\n",
  5151. "----------\n",
  5152. "LR 1.0000000000000002e-06\n",
  5153. "train: loss: 0.000148, bce: 0.000344, dice: 1.000654\n",
  5154. "val: loss: 0.000153, bce: 0.000376, dice: 1.001230\n",
  5155. "saving best model\n",
  5156. "0m 9s\n",
  5157. "\n",
  5158. "\n",
  5159. "Epoch 452/799\n",
  5160. "----------\n",
  5161. "LR 1.0000000000000002e-06\n",
  5162. "train: loss: 0.000148, bce: 0.000344, dice: 1.000654\n",
  5163. "val: loss: 0.000153, bce: 0.000376, dice: 1.001230\n",
  5164. "saving best model\n",
  5165. "0m 9s\n",
  5166. "\n",
  5167. "\n",
  5168. "Epoch 453/799\n",
  5169. "----------\n",
  5170. "LR 1.0000000000000002e-06\n",
  5171. "train: loss: 0.000148, bce: 0.000344, dice: 1.000654\n",
  5172. "val: loss: 0.000153, bce: 0.000376, dice: 1.001232\n",
  5173. "saving best model\n",
  5174. "0m 9s\n",
  5175. "\n",
  5176. "\n",
  5177. "Epoch 454/799\n",
  5178. "----------\n",
  5179. "LR 1.0000000000000002e-06\n",
  5180. "train: loss: 0.000148, bce: 0.000344, dice: 1.000654\n",
  5181. "val: loss: 0.000153, bce: 0.000376, dice: 1.001231\n",
  5182. "saving best model\n",
  5183. "0m 9s\n",
  5184. "\n",
  5185. "\n",
  5186. "Epoch 455/799\n",
  5187. "----------\n",
  5188. "LR 1.0000000000000002e-06\n",
  5189. "train: loss: 0.000148, bce: 0.000343, dice: 1.000654\n",
  5190. "val: loss: 0.000153, bce: 0.000376, dice: 1.001231\n",
  5191. "saving best model\n",
  5192. "0m 9s\n",
  5193. "\n",
  5194. "\n",
  5195. "Epoch 456/799\n",
  5196. "----------\n",
  5197. "LR 1.0000000000000002e-06\n",
  5198. "train: loss: 0.000148, bce: 0.000344, dice: 1.000654\n",
  5199. "val: loss: 0.000153, bce: 0.000375, dice: 1.001231\n",
  5200. "saving best model\n",
  5201. "0m 9s\n",
  5202. "\n",
  5203. "\n",
  5204. "Epoch 457/799\n",
  5205. "----------\n",
  5206. "LR 1.0000000000000002e-06\n",
  5207. "train: loss: 0.000148, bce: 0.000343, dice: 1.000654\n",
  5208. "val: loss: 0.000153, bce: 0.000375, dice: 1.001230\n",
  5209. "saving best model\n",
  5210. "0m 9s\n",
  5211. "\n",
  5212. "\n",
  5213. "Epoch 458/799\n",
  5214. "----------\n",
  5215. "LR 1.0000000000000002e-06\n",
  5216. "train: loss: 0.000148, bce: 0.000343, dice: 1.000654\n",
  5217. "val: loss: 0.000153, bce: 0.000375, dice: 1.001228\n",
  5218. "saving best model\n",
  5219. "0m 9s\n",
  5220. "\n",
  5221. "\n",
  5222. "Epoch 459/799\n",
  5223. "----------\n",
  5224. "LR 1.0000000000000002e-06\n",
  5225. "train: loss: 0.000148, bce: 0.000343, dice: 1.000654\n",
  5226. "val: loss: 0.000153, bce: 0.000375, dice: 1.001226\n",
  5227. "saving best model\n",
  5228. "0m 9s\n",
  5229. "\n",
  5230. "\n",
  5231. "Epoch 460/799\n",
  5232. "----------\n",
  5233. "LR 1.0000000000000002e-06\n",
  5234. "train: loss: 0.000148, bce: 0.000343, dice: 1.000653\n",
  5235. "val: loss: 0.000153, bce: 0.000375, dice: 1.001228\n",
  5236. "saving best model\n",
  5237. "0m 9s\n",
  5238. "\n",
  5239. "\n",
  5240. "Epoch 461/799\n",
  5241. "----------\n",
  5242. "LR 1.0000000000000002e-06\n",
  5243. "train: loss: 0.000148, bce: 0.000343, dice: 1.000654\n",
  5244. "val: loss: 0.000153, bce: 0.000375, dice: 1.001226\n",
  5245. "saving best model\n",
  5246. "0m 9s\n",
  5247. "\n",
  5248. "\n",
  5249. "Epoch 462/799\n",
  5250. "----------\n",
  5251. "LR 1.0000000000000002e-06\n",
  5252. "train: loss: 0.000148, bce: 0.000343, dice: 1.000652\n",
  5253. "val: loss: 0.000153, bce: 0.000375, dice: 1.001227\n",
  5254. "saving best model\n",
  5255. "0m 9s\n",
  5256. "\n",
  5257. "\n",
  5258. "Epoch 463/799\n",
  5259. "----------\n",
  5260. "LR 1.0000000000000002e-06\n",
  5261. "train: loss: 0.000148, bce: 0.000343, dice: 1.000653\n",
  5262. "val: loss: 0.000153, bce: 0.000375, dice: 1.001226\n",
  5263. "saving best model\n",
  5264. "0m 9s\n",
  5265. "\n",
  5266. "\n",
  5267. "Epoch 464/799\n",
  5268. "----------\n",
  5269. "LR 1.0000000000000002e-06\n",
  5270. "train: loss: 0.000148, bce: 0.000343, dice: 1.000653\n",
  5271. "val: loss: 0.000153, bce: 0.000374, dice: 1.001225\n",
  5272. "saving best model\n",
  5273. "0m 9s\n",
  5274. "\n",
  5275. "\n",
  5276. "Epoch 465/799\n",
  5277. "----------\n",
  5278. "LR 1.0000000000000002e-06\n",
  5279. "train: loss: 0.000148, bce: 0.000343, dice: 1.000652\n",
  5280. "val: loss: 0.000153, bce: 0.000374, dice: 1.001224\n",
  5281. "saving best model\n",
  5282. "0m 9s\n",
  5283. "\n",
  5284. "\n",
  5285. "Epoch 466/799\n",
  5286. "----------\n",
  5287. "LR 1.0000000000000002e-06\n",
  5288. "train: loss: 0.000148, bce: 0.000342, dice: 1.000652\n",
  5289. "val: loss: 0.000153, bce: 0.000374, dice: 1.001227\n",
  5290. "saving best model\n",
  5291. "0m 9s\n",
  5292. "\n",
  5293. "\n",
  5294. "Epoch 467/799\n",
  5295. "----------\n",
  5296. "LR 1.0000000000000002e-06\n",
  5297. "train: loss: 0.000148, bce: 0.000342, dice: 1.000652\n",
  5298. "val: loss: 0.000153, bce: 0.000374, dice: 1.001227\n",
  5299. "saving best model\n",
  5300. "0m 9s\n",
  5301. "\n",
  5302. "\n",
  5303. "Epoch 468/799\n",
  5304. "----------\n",
  5305. "LR 1.0000000000000002e-06\n",
  5306. "train: loss: 0.000148, bce: 0.000342, dice: 1.000653\n",
  5307. "val: loss: 0.000153, bce: 0.000374, dice: 1.001225\n",
  5308. "saving best model\n",
  5309. "0m 9s\n",
  5310. "\n",
  5311. "\n",
  5312. "Epoch 469/799\n",
  5313. "----------\n",
  5314. "LR 1.0000000000000002e-06\n",
  5315. "train: loss: 0.000148, bce: 0.000342, dice: 1.000652\n",
  5316. "val: loss: 0.000153, bce: 0.000374, dice: 1.001225\n",
  5317. "saving best model\n",
  5318. "0m 9s\n",
  5319. "\n",
  5320. "\n",
  5321. "Epoch 470/799\n",
  5322. "----------\n",
  5323. "LR 1.0000000000000002e-06\n",
  5324. "train: loss: 0.000148, bce: 0.000342, dice: 1.000652\n",
  5325. "val: loss: 0.000153, bce: 0.000374, dice: 1.001224\n",
  5326. "saving best model\n",
  5327. "0m 9s\n",
  5328. "\n",
  5329. "\n",
  5330. "Epoch 471/799\n",
  5331. "----------\n",
  5332. "LR 1.0000000000000002e-06\n",
  5333. "train: loss: 0.000148, bce: 0.000342, dice: 1.000652\n",
  5334. "val: loss: 0.000153, bce: 0.000374, dice: 1.001223\n",
  5335. "saving best model\n",
  5336. "0m 9s\n",
  5337. "\n",
  5338. "\n",
  5339. "Epoch 472/799\n",
  5340. "----------\n",
  5341. "LR 1.0000000000000002e-06\n",
  5342. "train: loss: 0.000148, bce: 0.000342, dice: 1.000651\n",
  5343. "val: loss: 0.000153, bce: 0.000373, dice: 1.001223\n",
  5344. "saving best model\n",
  5345. "0m 9s\n",
  5346. "\n",
  5347. "\n",
  5348. "Epoch 473/799\n",
  5349. "----------\n",
  5350. "LR 1.0000000000000002e-06\n",
  5351. "train: loss: 0.000148, bce: 0.000342, dice: 1.000652\n",
  5352. "val: loss: 0.000153, bce: 0.000373, dice: 1.001226\n",
  5353. "saving best model\n",
  5354. "0m 9s\n",
  5355. "\n",
  5356. "\n",
  5357. "Epoch 474/799\n",
  5358. "----------\n",
  5359. "LR 1.0000000000000002e-06\n",
  5360. "train: loss: 0.000148, bce: 0.000342, dice: 1.000653\n",
  5361. "val: loss: 0.000153, bce: 0.000373, dice: 1.001224\n",
  5362. "saving best model\n",
  5363. "0m 9s\n",
  5364. "\n",
  5365. "\n",
  5366. "Epoch 475/799\n",
  5367. "----------\n",
  5368. "LR 1.0000000000000002e-06\n",
  5369. "train: loss: 0.000148, bce: 0.000342, dice: 1.000652\n",
  5370. "val: loss: 0.000152, bce: 0.000373, dice: 1.001224\n",
  5371. "saving best model\n",
  5372. "0m 9s\n",
  5373. "\n",
  5374. "\n",
  5375. "Epoch 476/799\n",
  5376. "----------\n",
  5377. "LR 1.0000000000000002e-06\n",
  5378. "train: loss: 0.000148, bce: 0.000342, dice: 1.000652\n",
  5379. "val: loss: 0.000152, bce: 0.000373, dice: 1.001223\n",
  5380. "saving best model\n",
  5381. "0m 9s\n",
  5382. "\n",
  5383. "\n",
  5384. "Epoch 477/799\n",
  5385. "----------\n",
  5386. "LR 1.0000000000000002e-06\n",
  5387. "train: loss: 0.000148, bce: 0.000342, dice: 1.000652\n",
  5388. "val: loss: 0.000152, bce: 0.000373, dice: 1.001220\n",
  5389. "saving best model\n",
  5390. "0m 9s\n",
  5391. "\n",
  5392. "\n",
  5393. "Epoch 478/799\n",
  5394. "----------\n",
  5395. "LR 1.0000000000000002e-06\n",
  5396. "train: loss: 0.000148, bce: 0.000341, dice: 1.000652\n",
  5397. "val: loss: 0.000152, bce: 0.000373, dice: 1.001220\n",
  5398. "saving best model\n",
  5399. "0m 9s\n",
  5400. "\n",
  5401. "\n",
  5402. "Epoch 479/799\n",
  5403. "----------\n",
  5404. "LR 1.0000000000000002e-06\n",
  5405. "train: loss: 0.000148, bce: 0.000341, dice: 1.000651\n",
  5406. "val: loss: 0.000152, bce: 0.000373, dice: 1.001223\n",
  5407. "saving best model\n",
  5408. "0m 9s\n",
  5409. "\n",
  5410. "\n",
  5411. "Epoch 480/799\n",
  5412. "----------\n",
  5413. "LR 1.0000000000000002e-06\n",
  5414. "train: loss: 0.000148, bce: 0.000341, dice: 1.000651\n",
  5415. "val: loss: 0.000152, bce: 0.000372, dice: 1.001222\n",
  5416. "saving best model\n",
  5417. "0m 9s\n",
  5418. "\n",
  5419. "\n",
  5420. "Epoch 481/799\n",
  5421. "----------\n",
  5422. "LR 1.0000000000000002e-06\n",
  5423. "train: loss: 0.000148, bce: 0.000341, dice: 1.000651\n",
  5424. "val: loss: 0.000152, bce: 0.000372, dice: 1.001220\n",
  5425. "saving best model\n",
  5426. "0m 9s\n",
  5427. "\n",
  5428. "\n",
  5429. "Epoch 482/799\n",
  5430. "----------\n",
  5431. "LR 1.0000000000000002e-06\n",
  5432. "train: loss: 0.000148, bce: 0.000341, dice: 1.000650\n",
  5433. "val: loss: 0.000152, bce: 0.000372, dice: 1.001220\n",
  5434. "saving best model\n",
  5435. "0m 9s\n",
  5436. "\n",
  5437. "\n",
  5438. "Epoch 483/799\n",
  5439. "----------\n",
  5440. "LR 1.0000000000000002e-06\n",
  5441. "train: loss: 0.000147, bce: 0.000341, dice: 1.000650\n",
  5442. "val: loss: 0.000152, bce: 0.000372, dice: 1.001220\n",
  5443. "saving best model\n",
  5444. "0m 9s\n",
  5445. "\n",
  5446. "\n",
  5447. "Epoch 484/799\n",
  5448. "----------\n",
  5449. "LR 1.0000000000000002e-06\n",
  5450. "train: loss: 0.000147, bce: 0.000341, dice: 1.000650\n",
  5451. "val: loss: 0.000152, bce: 0.000372, dice: 1.001221\n",
  5452. "saving best model\n",
  5453. "0m 9s\n",
  5454. "\n",
  5455. "\n",
  5456. "Epoch 485/799\n",
  5457. "----------\n",
  5458. "LR 1.0000000000000002e-06\n",
  5459. "train: loss: 0.000147, bce: 0.000340, dice: 1.000651\n",
  5460. "val: loss: 0.000152, bce: 0.000372, dice: 1.001220\n",
  5461. "saving best model\n",
  5462. "0m 9s\n",
  5463. "\n",
  5464. "\n",
  5465. "Epoch 486/799\n",
  5466. "----------\n",
  5467. "LR 1.0000000000000002e-06\n",
  5468. "train: loss: 0.000147, bce: 0.000340, dice: 1.000650\n",
  5469. "val: loss: 0.000152, bce: 0.000372, dice: 1.001219\n",
  5470. "saving best model\n",
  5471. "0m 9s\n",
  5472. "\n",
  5473. "\n",
  5474. "Epoch 487/799\n",
  5475. "----------\n",
  5476. "LR 1.0000000000000002e-06\n",
  5477. "train: loss: 0.000147, bce: 0.000340, dice: 1.000650\n",
  5478. "val: loss: 0.000152, bce: 0.000372, dice: 1.001222\n",
  5479. "saving best model\n",
  5480. "0m 9s\n",
  5481. "\n",
  5482. "\n",
  5483. "Epoch 488/799\n",
  5484. "----------\n",
  5485. "LR 1.0000000000000002e-06\n",
  5486. "train: loss: 0.000148, bce: 0.000341, dice: 1.000650\n",
  5487. "val: loss: 0.000152, bce: 0.000372, dice: 1.001218\n",
  5488. "saving best model\n",
  5489. "0m 9s\n",
  5490. "\n",
  5491. "\n",
  5492. "Epoch 489/799\n",
  5493. "----------\n",
  5494. "LR 1.0000000000000002e-06\n",
  5495. "train: loss: 0.000147, bce: 0.000340, dice: 1.000650\n",
  5496. "val: loss: 0.000152, bce: 0.000372, dice: 1.001220\n",
  5497. "saving best model\n",
  5498. "0m 9s\n",
  5499. "\n",
  5500. "\n",
  5501. "Epoch 490/799\n",
  5502. "----------\n",
  5503. "LR 1.0000000000000002e-06\n",
  5504. "train: loss: 0.000147, bce: 0.000341, dice: 1.000651\n",
  5505. "val: loss: 0.000152, bce: 0.000371, dice: 1.001216\n",
  5506. "saving best model\n",
  5507. "0m 9s\n",
  5508. "\n",
  5509. "\n",
  5510. "Epoch 491/799\n",
  5511. "----------\n",
  5512. "LR 1.0000000000000002e-06\n",
  5513. "train: loss: 0.000147, bce: 0.000340, dice: 1.000649\n",
  5514. "val: loss: 0.000152, bce: 0.000371, dice: 1.001217\n",
  5515. "saving best model\n",
  5516. "0m 9s\n",
  5517. "\n",
  5518. "\n",
  5519. "Epoch 492/799\n",
  5520. "----------\n",
  5521. "LR 1.0000000000000002e-06\n",
  5522. "train: loss: 0.000147, bce: 0.000340, dice: 1.000650\n",
  5523. "val: loss: 0.000152, bce: 0.000371, dice: 1.001216\n",
  5524. "saving best model\n",
  5525. "0m 9s\n",
  5526. "\n",
  5527. "\n",
  5528. "Epoch 493/799\n",
  5529. "----------\n",
  5530. "LR 1.0000000000000002e-06\n",
  5531. "train: loss: 0.000147, bce: 0.000340, dice: 1.000649\n",
  5532. "val: loss: 0.000152, bce: 0.000371, dice: 1.001217\n",
  5533. "saving best model\n",
  5534. "0m 9s\n",
  5535. "\n",
  5536. "\n",
  5537. "Epoch 494/799\n",
  5538. "----------\n",
  5539. "LR 1.0000000000000002e-06\n",
  5540. "train: loss: 0.000147, bce: 0.000340, dice: 1.000649\n",
  5541. "val: loss: 0.000152, bce: 0.000371, dice: 1.001215\n",
  5542. "saving best model\n",
  5543. "0m 9s\n",
  5544. "\n",
  5545. "\n",
  5546. "Epoch 495/799\n",
  5547. "----------\n",
  5548. "LR 1.0000000000000002e-06\n",
  5549. "train: loss: 0.000147, bce: 0.000340, dice: 1.000649\n",
  5550. "val: loss: 0.000152, bce: 0.000371, dice: 1.001215\n",
  5551. "saving best model\n",
  5552. "0m 9s\n",
  5553. "\n",
  5554. "\n",
  5555. "Epoch 496/799\n",
  5556. "----------\n",
  5557. "LR 1.0000000000000002e-06\n",
  5558. "train: loss: 0.000147, bce: 0.000340, dice: 1.000648\n",
  5559. "val: loss: 0.000152, bce: 0.000371, dice: 1.001217\n",
  5560. "saving best model\n",
  5561. "0m 9s\n",
  5562. "\n",
  5563. "\n",
  5564. "Epoch 497/799\n",
  5565. "----------\n",
  5566. "LR 1.0000000000000002e-06\n",
  5567. "train: loss: 0.000147, bce: 0.000340, dice: 1.000649\n",
  5568. "val: loss: 0.000152, bce: 0.000371, dice: 1.001217\n",
  5569. "saving best model\n",
  5570. "0m 9s\n",
  5571. "\n",
  5572. "\n",
  5573. "Epoch 498/799\n",
  5574. "----------\n",
  5575. "LR 1.0000000000000002e-06\n",
  5576. "train: loss: 0.000147, bce: 0.000340, dice: 1.000649\n",
  5577. "val: loss: 0.000152, bce: 0.000370, dice: 1.001213\n",
  5578. "saving best model\n",
  5579. "0m 9s\n",
  5580. "\n",
  5581. "\n",
  5582. "Epoch 499/799\n",
  5583. "----------\n",
  5584. "LR 1.0000000000000002e-06\n",
  5585. "train: loss: 0.000147, bce: 0.000339, dice: 1.000649\n",
  5586. "val: loss: 0.000152, bce: 0.000370, dice: 1.001214\n",
  5587. "saving best model\n",
  5588. "0m 9s\n",
  5589. "\n",
  5590. "\n",
  5591. "Epoch 500/799\n",
  5592. "----------\n",
  5593. "LR 1.0000000000000002e-06\n",
  5594. "train: loss: 0.000147, bce: 0.000339, dice: 1.000648\n",
  5595. "val: loss: 0.000151, bce: 0.000370, dice: 1.001217\n",
  5596. "saving best model\n",
  5597. "0m 9s\n",
  5598. "\n",
  5599. "\n",
  5600. "Epoch 501/799\n",
  5601. "----------\n",
  5602. "LR 1.0000000000000002e-06\n",
  5603. "train: loss: 0.000147, bce: 0.000339, dice: 1.000649\n",
  5604. "val: loss: 0.000151, bce: 0.000370, dice: 1.001211\n",
  5605. "saving best model\n",
  5606. "0m 9s\n",
  5607. "\n",
  5608. "\n",
  5609. "Epoch 502/799\n",
  5610. "----------\n",
  5611. "LR 1.0000000000000002e-06\n",
  5612. "train: loss: 0.000147, bce: 0.000339, dice: 1.000647\n",
  5613. "val: loss: 0.000151, bce: 0.000370, dice: 1.001215\n",
  5614. "saving best model\n",
  5615. "0m 9s\n",
  5616. "\n",
  5617. "\n",
  5618. "Epoch 503/799\n",
  5619. "----------\n",
  5620. "LR 1.0000000000000002e-06\n",
  5621. "train: loss: 0.000147, bce: 0.000339, dice: 1.000649\n",
  5622. "val: loss: 0.000151, bce: 0.000370, dice: 1.001211\n",
  5623. "saving best model\n",
  5624. "0m 9s\n",
  5625. "\n",
  5626. "\n",
  5627. "Epoch 504/799\n",
  5628. "----------\n",
  5629. "LR 1.0000000000000002e-06\n",
  5630. "train: loss: 0.000147, bce: 0.000338, dice: 1.000647\n",
  5631. "val: loss: 0.000151, bce: 0.000370, dice: 1.001215\n",
  5632. "saving best model\n",
  5633. "0m 9s\n",
  5634. "\n",
  5635. "\n",
  5636. "Epoch 505/799\n",
  5637. "----------\n",
  5638. "LR 1.0000000000000002e-06\n",
  5639. "train: loss: 0.000147, bce: 0.000339, dice: 1.000648\n",
  5640. "val: loss: 0.000151, bce: 0.000370, dice: 1.001211\n",
  5641. "saving best model\n",
  5642. "0m 9s\n",
  5643. "\n",
  5644. "\n",
  5645. "Epoch 506/799\n",
  5646. "----------\n",
  5647. "LR 1.0000000000000002e-06\n",
  5648. "train: loss: 0.000147, bce: 0.000339, dice: 1.000646\n",
  5649. "val: loss: 0.000151, bce: 0.000369, dice: 1.001217\n",
  5650. "saving best model\n",
  5651. "0m 9s\n",
  5652. "\n",
  5653. "\n",
  5654. "Epoch 507/799\n",
  5655. "----------\n",
  5656. "LR 1.0000000000000002e-06\n",
  5657. "train: loss: 0.000147, bce: 0.000338, dice: 1.000648\n",
  5658. "val: loss: 0.000151, bce: 0.000369, dice: 1.001215\n",
  5659. "saving best model\n",
  5660. "0m 9s\n",
  5661. "\n",
  5662. "\n",
  5663. "Epoch 508/799\n",
  5664. "----------\n",
  5665. "LR 1.0000000000000002e-06\n",
  5666. "train: loss: 0.000147, bce: 0.000338, dice: 1.000647\n",
  5667. "val: loss: 0.000151, bce: 0.000369, dice: 1.001214\n",
  5668. "saving best model\n",
  5669. "0m 9s\n",
  5670. "\n",
  5671. "\n",
  5672. "Epoch 509/799\n",
  5673. "----------\n",
  5674. "LR 1.0000000000000002e-06\n",
  5675. "train: loss: 0.000147, bce: 0.000338, dice: 1.000648\n",
  5676. "val: loss: 0.000151, bce: 0.000369, dice: 1.001210\n",
  5677. "saving best model\n",
  5678. "0m 9s\n",
  5679. "\n",
  5680. "\n",
  5681. "Epoch 510/799\n",
  5682. "----------\n",
  5683. "LR 1.0000000000000002e-06\n",
  5684. "train: loss: 0.000147, bce: 0.000338, dice: 1.000648\n",
  5685. "val: loss: 0.000151, bce: 0.000369, dice: 1.001207\n",
  5686. "saving best model\n",
  5687. "0m 9s\n",
  5688. "\n",
  5689. "\n",
  5690. "Epoch 511/799\n",
  5691. "----------\n",
  5692. "LR 1.0000000000000002e-06\n",
  5693. "train: loss: 0.000147, bce: 0.000338, dice: 1.000646\n",
  5694. "val: loss: 0.000151, bce: 0.000369, dice: 1.001212\n",
  5695. "saving best model\n",
  5696. "0m 9s\n",
  5697. "\n",
  5698. "\n",
  5699. "Epoch 512/799\n",
  5700. "----------\n",
  5701. "LR 1.0000000000000002e-06\n",
  5702. "train: loss: 0.000147, bce: 0.000338, dice: 1.000647\n",
  5703. "val: loss: 0.000151, bce: 0.000368, dice: 1.001204\n",
  5704. "0m 9s\n",
  5705. "\n",
  5706. "\n",
  5707. "Epoch 513/799\n",
  5708. "----------\n",
  5709. "LR 1.0000000000000002e-06\n",
  5710. "train: loss: 0.000147, bce: 0.000338, dice: 1.000645\n",
  5711. "val: loss: 0.000151, bce: 0.000369, dice: 1.001213\n",
  5712. "saving best model\n",
  5713. "0m 9s\n",
  5714. "\n",
  5715. "\n",
  5716. "Epoch 514/799\n",
  5717. "----------\n",
  5718. "LR 1.0000000000000002e-06\n",
  5719. "train: loss: 0.000147, bce: 0.000338, dice: 1.000648\n",
  5720. "val: loss: 0.000151, bce: 0.000368, dice: 1.001207\n",
  5721. "saving best model\n",
  5722. "0m 9s\n",
  5723. "\n",
  5724. "\n",
  5725. "Epoch 515/799\n",
  5726. "----------\n",
  5727. "LR 1.0000000000000002e-06\n",
  5728. "train: loss: 0.000147, bce: 0.000338, dice: 1.000647\n",
  5729. "val: loss: 0.000151, bce: 0.000368, dice: 1.001206\n",
  5730. "saving best model\n",
  5731. "0m 9s\n",
  5732. "\n",
  5733. "\n",
  5734. "Epoch 516/799\n",
  5735. "----------\n",
  5736. "LR 1.0000000000000002e-06\n",
  5737. "train: loss: 0.000147, bce: 0.000338, dice: 1.000646\n",
  5738. "val: loss: 0.000151, bce: 0.000368, dice: 1.001209\n",
  5739. "saving best model\n",
  5740. "0m 9s\n",
  5741. "\n",
  5742. "\n",
  5743. "Epoch 517/799\n",
  5744. "----------\n",
  5745. "LR 1.0000000000000002e-06\n",
  5746. "train: loss: 0.000146, bce: 0.000338, dice: 1.000646\n",
  5747. "val: loss: 0.000151, bce: 0.000368, dice: 1.001210\n",
  5748. "saving best model\n",
  5749. "0m 9s\n",
  5750. "\n",
  5751. "\n",
  5752. "Epoch 518/799\n",
  5753. "----------\n",
  5754. "LR 1.0000000000000002e-06\n",
  5755. "train: loss: 0.000147, bce: 0.000337, dice: 1.000645\n",
  5756. "val: loss: 0.000151, bce: 0.000368, dice: 1.001212\n",
  5757. "saving best model\n",
  5758. "0m 9s\n",
  5759. "\n",
  5760. "\n",
  5761. "Epoch 519/799\n",
  5762. "----------\n",
  5763. "LR 1.0000000000000002e-06\n",
  5764. "train: loss: 0.000146, bce: 0.000337, dice: 1.000646\n",
  5765. "val: loss: 0.000151, bce: 0.000368, dice: 1.001211\n",
  5766. "saving best model\n",
  5767. "0m 9s\n",
  5768. "\n",
  5769. "\n",
  5770. "Epoch 520/799\n",
  5771. "----------\n",
  5772. "LR 1.0000000000000002e-06\n",
  5773. "train: loss: 0.000146, bce: 0.000337, dice: 1.000646\n",
  5774. "val: loss: 0.000151, bce: 0.000368, dice: 1.001209\n",
  5775. "saving best model\n",
  5776. "0m 9s\n",
  5777. "\n",
  5778. "\n",
  5779. "Epoch 521/799\n",
  5780. "----------\n",
  5781. "LR 1.0000000000000002e-06\n",
  5782. "train: loss: 0.000146, bce: 0.000337, dice: 1.000646\n",
  5783. "val: loss: 0.000151, bce: 0.000368, dice: 1.001208\n",
  5784. "saving best model\n",
  5785. "0m 9s\n",
  5786. "\n",
  5787. "\n",
  5788. "Epoch 522/799\n",
  5789. "----------\n",
  5790. "LR 1.0000000000000002e-06\n",
  5791. "train: loss: 0.000146, bce: 0.000337, dice: 1.000645\n",
  5792. "val: loss: 0.000151, bce: 0.000368, dice: 1.001208\n",
  5793. "saving best model\n",
  5794. "0m 9s\n",
  5795. "\n",
  5796. "\n",
  5797. "Epoch 523/799\n",
  5798. "----------\n",
  5799. "LR 1.0000000000000002e-06\n",
  5800. "train: loss: 0.000146, bce: 0.000337, dice: 1.000646\n",
  5801. "val: loss: 0.000151, bce: 0.000367, dice: 1.001205\n",
  5802. "saving best model\n",
  5803. "0m 9s\n",
  5804. "\n",
  5805. "\n",
  5806. "Epoch 524/799\n",
  5807. "----------\n",
  5808. "LR 1.0000000000000002e-06\n",
  5809. "train: loss: 0.000146, bce: 0.000337, dice: 1.000645\n",
  5810. "val: loss: 0.000151, bce: 0.000367, dice: 1.001203\n",
  5811. "saving best model\n",
  5812. "0m 9s\n",
  5813. "\n",
  5814. "\n",
  5815. "Epoch 525/799\n",
  5816. "----------\n",
  5817. "LR 1.0000000000000002e-06\n",
  5818. "train: loss: 0.000146, bce: 0.000337, dice: 1.000645\n",
  5819. "val: loss: 0.000150, bce: 0.000367, dice: 1.001203\n",
  5820. "saving best model\n",
  5821. "0m 9s\n",
  5822. "\n",
  5823. "\n",
  5824. "Epoch 526/799\n",
  5825. "----------\n",
  5826. "LR 1.0000000000000002e-06\n",
  5827. "train: loss: 0.000146, bce: 0.000337, dice: 1.000645\n",
  5828. "val: loss: 0.000150, bce: 0.000367, dice: 1.001201\n",
  5829. "saving best model\n",
  5830. "0m 9s\n",
  5831. "\n",
  5832. "\n",
  5833. "Epoch 527/799\n",
  5834. "----------\n",
  5835. "LR 1.0000000000000002e-06\n",
  5836. "train: loss: 0.000146, bce: 0.000337, dice: 1.000644\n",
  5837. "val: loss: 0.000150, bce: 0.000367, dice: 1.001204\n",
  5838. "saving best model\n",
  5839. "0m 9s\n",
  5840. "\n",
  5841. "\n",
  5842. "Epoch 528/799\n",
  5843. "----------\n",
  5844. "LR 1.0000000000000002e-06\n",
  5845. "train: loss: 0.000146, bce: 0.000336, dice: 1.000645\n",
  5846. "val: loss: 0.000150, bce: 0.000367, dice: 1.001204\n",
  5847. "saving best model\n",
  5848. "0m 9s\n",
  5849. "\n",
  5850. "\n",
  5851. "Epoch 529/799\n",
  5852. "----------\n",
  5853. "LR 1.0000000000000002e-06\n",
  5854. "train: loss: 0.000146, bce: 0.000336, dice: 1.000644\n",
  5855. "val: loss: 0.000150, bce: 0.000366, dice: 1.001203\n",
  5856. "saving best model\n",
  5857. "0m 9s\n",
  5858. "\n",
  5859. "\n",
  5860. "Epoch 530/799\n",
  5861. "----------\n",
  5862. "LR 1.0000000000000002e-06\n",
  5863. "train: loss: 0.000146, bce: 0.000336, dice: 1.000644\n",
  5864. "val: loss: 0.000150, bce: 0.000367, dice: 1.001205\n",
  5865. "saving best model\n",
  5866. "0m 9s\n",
  5867. "\n",
  5868. "\n",
  5869. "Epoch 531/799\n",
  5870. "----------\n",
  5871. "LR 1.0000000000000002e-06\n",
  5872. "train: loss: 0.000146, bce: 0.000336, dice: 1.000645\n",
  5873. "val: loss: 0.000150, bce: 0.000366, dice: 1.001203\n",
  5874. "saving best model\n",
  5875. "0m 9s\n",
  5876. "\n",
  5877. "\n",
  5878. "Epoch 532/799\n",
  5879. "----------\n",
  5880. "LR 1.0000000000000002e-06\n",
  5881. "train: loss: 0.000146, bce: 0.000336, dice: 1.000644\n",
  5882. "val: loss: 0.000150, bce: 0.000366, dice: 1.001202\n",
  5883. "saving best model\n",
  5884. "0m 9s\n",
  5885. "\n",
  5886. "\n",
  5887. "Epoch 533/799\n",
  5888. "----------\n",
  5889. "LR 1.0000000000000002e-06\n",
  5890. "train: loss: 0.000146, bce: 0.000336, dice: 1.000644\n",
  5891. "val: loss: 0.000150, bce: 0.000366, dice: 1.001205\n",
  5892. "saving best model\n",
  5893. "0m 9s\n",
  5894. "\n",
  5895. "\n",
  5896. "Epoch 534/799\n",
  5897. "----------\n",
  5898. "LR 1.0000000000000002e-06\n",
  5899. "train: loss: 0.000146, bce: 0.000336, dice: 1.000645\n",
  5900. "val: loss: 0.000150, bce: 0.000366, dice: 1.001203\n",
  5901. "saving best model\n",
  5902. "0m 9s\n",
  5903. "\n",
  5904. "\n",
  5905. "Epoch 535/799\n",
  5906. "----------\n",
  5907. "LR 1.0000000000000002e-06\n",
  5908. "train: loss: 0.000146, bce: 0.000336, dice: 1.000644\n",
  5909. "val: loss: 0.000150, bce: 0.000366, dice: 1.001204\n",
  5910. "saving best model\n",
  5911. "0m 9s\n",
  5912. "\n",
  5913. "\n",
  5914. "Epoch 536/799\n",
  5915. "----------\n",
  5916. "LR 1.0000000000000002e-06\n",
  5917. "train: loss: 0.000146, bce: 0.000336, dice: 1.000644\n",
  5918. "val: loss: 0.000150, bce: 0.000365, dice: 1.001201\n",
  5919. "saving best model\n",
  5920. "0m 9s\n",
  5921. "\n",
  5922. "\n",
  5923. "Epoch 537/799\n",
  5924. "----------\n",
  5925. "LR 1.0000000000000002e-06\n",
  5926. "train: loss: 0.000146, bce: 0.000335, dice: 1.000643\n",
  5927. "val: loss: 0.000150, bce: 0.000366, dice: 1.001207\n",
  5928. "saving best model\n",
  5929. "0m 9s\n",
  5930. "\n",
  5931. "\n",
  5932. "Epoch 538/799\n",
  5933. "----------\n",
  5934. "LR 1.0000000000000002e-06\n",
  5935. "train: loss: 0.000146, bce: 0.000335, dice: 1.000644\n",
  5936. "val: loss: 0.000150, bce: 0.000366, dice: 1.001201\n",
  5937. "saving best model\n",
  5938. "0m 9s\n",
  5939. "\n",
  5940. "\n",
  5941. "Epoch 539/799\n",
  5942. "----------\n",
  5943. "LR 1.0000000000000002e-06\n",
  5944. "train: loss: 0.000146, bce: 0.000335, dice: 1.000644\n",
  5945. "val: loss: 0.000150, bce: 0.000365, dice: 1.001203\n",
  5946. "saving best model\n",
  5947. "0m 9s\n",
  5948. "\n",
  5949. "\n",
  5950. "Epoch 540/799\n",
  5951. "----------\n",
  5952. "LR 1.0000000000000002e-06\n",
  5953. "train: loss: 0.000146, bce: 0.000335, dice: 1.000644\n",
  5954. "val: loss: 0.000150, bce: 0.000365, dice: 1.001201\n",
  5955. "saving best model\n",
  5956. "0m 9s\n",
  5957. "\n",
  5958. "\n",
  5959. "Epoch 541/799\n",
  5960. "----------\n",
  5961. "LR 1.0000000000000002e-06\n",
  5962. "train: loss: 0.000146, bce: 0.000336, dice: 1.000643\n",
  5963. "val: loss: 0.000150, bce: 0.000365, dice: 1.001199\n",
  5964. "saving best model\n",
  5965. "0m 9s\n",
  5966. "\n",
  5967. "\n",
  5968. "Epoch 542/799\n",
  5969. "----------\n",
  5970. "LR 1.0000000000000002e-06\n",
  5971. "train: loss: 0.000146, bce: 0.000335, dice: 1.000643\n",
  5972. "val: loss: 0.000150, bce: 0.000365, dice: 1.001201\n",
  5973. "saving best model\n",
  5974. "0m 9s\n",
  5975. "\n",
  5976. "\n",
  5977. "Epoch 543/799\n",
  5978. "----------\n",
  5979. "LR 1.0000000000000002e-06\n",
  5980. "train: loss: 0.000146, bce: 0.000335, dice: 1.000643\n",
  5981. "val: loss: 0.000150, bce: 0.000365, dice: 1.001200\n",
  5982. "saving best model\n",
  5983. "0m 9s\n",
  5984. "\n",
  5985. "\n",
  5986. "Epoch 544/799\n",
  5987. "----------\n",
  5988. "LR 1.0000000000000002e-06\n",
  5989. "train: loss: 0.000146, bce: 0.000335, dice: 1.000643\n",
  5990. "val: loss: 0.000150, bce: 0.000365, dice: 1.001195\n",
  5991. "saving best model\n",
  5992. "0m 9s\n",
  5993. "\n",
  5994. "\n",
  5995. "Epoch 545/799\n",
  5996. "----------\n",
  5997. "LR 1.0000000000000002e-06\n",
  5998. "train: loss: 0.000146, bce: 0.000335, dice: 1.000643\n",
  5999. "val: loss: 0.000150, bce: 0.000364, dice: 1.001194\n",
  6000. "saving best model\n",
  6001. "0m 9s\n",
  6002. "\n",
  6003. "\n",
  6004. "Epoch 546/799\n",
  6005. "----------\n",
  6006. "LR 1.0000000000000002e-06\n",
  6007. "train: loss: 0.000145, bce: 0.000335, dice: 1.000642\n",
  6008. "val: loss: 0.000150, bce: 0.000365, dice: 1.001198\n",
  6009. "saving best model\n",
  6010. "0m 9s\n",
  6011. "\n",
  6012. "\n",
  6013. "Epoch 547/799\n",
  6014. "----------\n",
  6015. "LR 1.0000000000000002e-06\n",
  6016. "train: loss: 0.000146, bce: 0.000334, dice: 1.000642\n",
  6017. "val: loss: 0.000150, bce: 0.000365, dice: 1.001199\n",
  6018. "saving best model\n",
  6019. "0m 9s\n",
  6020. "\n",
  6021. "\n",
  6022. "Epoch 548/799\n",
  6023. "----------\n",
  6024. "LR 1.0000000000000002e-06\n",
  6025. "train: loss: 0.000145, bce: 0.000335, dice: 1.000643\n",
  6026. "val: loss: 0.000149, bce: 0.000365, dice: 1.001199\n",
  6027. "saving best model\n",
  6028. "0m 9s\n",
  6029. "\n",
  6030. "\n",
  6031. "Epoch 549/799\n",
  6032. "----------\n",
  6033. "LR 1.0000000000000002e-06\n",
  6034. "train: loss: 0.000145, bce: 0.000334, dice: 1.000643\n",
  6035. "val: loss: 0.000149, bce: 0.000364, dice: 1.001194\n",
  6036. "saving best model\n",
  6037. "0m 9s\n",
  6038. "\n",
  6039. "\n",
  6040. "Epoch 550/799\n",
  6041. "----------\n",
  6042. "LR 1.0000000000000002e-06\n",
  6043. "train: loss: 0.000145, bce: 0.000334, dice: 1.000641\n",
  6044. "val: loss: 0.000149, bce: 0.000364, dice: 1.001197\n",
  6045. "saving best model\n",
  6046. "0m 9s\n",
  6047. "\n",
  6048. "\n",
  6049. "Epoch 551/799\n",
  6050. "----------\n",
  6051. "LR 1.0000000000000002e-06\n",
  6052. "train: loss: 0.000145, bce: 0.000335, dice: 1.000642\n",
  6053. "val: loss: 0.000149, bce: 0.000364, dice: 1.001197\n",
  6054. "saving best model\n",
  6055. "0m 9s\n",
  6056. "\n",
  6057. "\n",
  6058. "Epoch 552/799\n",
  6059. "----------\n",
  6060. "LR 1.0000000000000002e-06\n",
  6061. "train: loss: 0.000145, bce: 0.000334, dice: 1.000642\n",
  6062. "val: loss: 0.000149, bce: 0.000364, dice: 1.001193\n",
  6063. "saving best model\n",
  6064. "0m 9s\n",
  6065. "\n",
  6066. "\n",
  6067. "Epoch 553/799\n",
  6068. "----------\n",
  6069. "LR 1.0000000000000002e-06\n",
  6070. "train: loss: 0.000145, bce: 0.000334, dice: 1.000641\n",
  6071. "val: loss: 0.000149, bce: 0.000364, dice: 1.001195\n",
  6072. "saving best model\n",
  6073. "0m 9s\n",
  6074. "\n",
  6075. "\n",
  6076. "Epoch 554/799\n",
  6077. "----------\n",
  6078. "LR 1.0000000000000002e-06\n",
  6079. "train: loss: 0.000145, bce: 0.000334, dice: 1.000641\n",
  6080. "val: loss: 0.000149, bce: 0.000364, dice: 1.001194\n",
  6081. "saving best model\n",
  6082. "0m 9s\n",
  6083. "\n",
  6084. "\n",
  6085. "Epoch 555/799\n",
  6086. "----------\n",
  6087. "LR 1.0000000000000002e-06\n",
  6088. "train: loss: 0.000145, bce: 0.000334, dice: 1.000642\n",
  6089. "val: loss: 0.000149, bce: 0.000364, dice: 1.001193\n",
  6090. "saving best model\n",
  6091. "0m 9s\n",
  6092. "\n",
  6093. "\n",
  6094. "Epoch 556/799\n",
  6095. "----------\n",
  6096. "LR 1.0000000000000002e-06\n",
  6097. "train: loss: 0.000145, bce: 0.000334, dice: 1.000641\n",
  6098. "val: loss: 0.000149, bce: 0.000364, dice: 1.001195\n",
  6099. "saving best model\n",
  6100. "0m 9s\n",
  6101. "\n",
  6102. "\n",
  6103. "Epoch 557/799\n",
  6104. "----------\n",
  6105. "LR 1.0000000000000002e-06\n",
  6106. "train: loss: 0.000145, bce: 0.000334, dice: 1.000641\n",
  6107. "val: loss: 0.000149, bce: 0.000363, dice: 1.001195\n",
  6108. "saving best model\n",
  6109. "0m 9s\n",
  6110. "\n",
  6111. "\n",
  6112. "Epoch 558/799\n",
  6113. "----------\n",
  6114. "LR 1.0000000000000002e-06\n",
  6115. "train: loss: 0.000145, bce: 0.000333, dice: 1.000641\n",
  6116. "val: loss: 0.000149, bce: 0.000363, dice: 1.001194\n",
  6117. "saving best model\n",
  6118. "0m 9s\n",
  6119. "\n",
  6120. "\n",
  6121. "Epoch 559/799\n",
  6122. "----------\n",
  6123. "LR 1.0000000000000002e-06\n",
  6124. "train: loss: 0.000145, bce: 0.000333, dice: 1.000641\n",
  6125. "val: loss: 0.000149, bce: 0.000363, dice: 1.001193\n",
  6126. "saving best model\n",
  6127. "0m 9s\n",
  6128. "\n",
  6129. "\n",
  6130. "Epoch 560/799\n",
  6131. "----------\n",
  6132. "LR 1.0000000000000002e-06\n",
  6133. "train: loss: 0.000145, bce: 0.000333, dice: 1.000640\n",
  6134. "val: loss: 0.000149, bce: 0.000363, dice: 1.001194\n",
  6135. "saving best model\n",
  6136. "0m 9s\n",
  6137. "\n",
  6138. "\n",
  6139. "Epoch 561/799\n",
  6140. "----------\n",
  6141. "LR 1.0000000000000002e-06\n",
  6142. "train: loss: 0.000145, bce: 0.000333, dice: 1.000641\n",
  6143. "val: loss: 0.000149, bce: 0.000363, dice: 1.001190\n",
  6144. "saving best model\n",
  6145. "0m 9s\n",
  6146. "\n",
  6147. "\n",
  6148. "Epoch 562/799\n",
  6149. "----------\n",
  6150. "LR 1.0000000000000002e-06\n",
  6151. "train: loss: 0.000145, bce: 0.000333, dice: 1.000640\n",
  6152. "val: loss: 0.000149, bce: 0.000363, dice: 1.001193\n",
  6153. "saving best model\n",
  6154. "0m 9s\n",
  6155. "\n",
  6156. "\n",
  6157. "Epoch 563/799\n",
  6158. "----------\n",
  6159. "LR 1.0000000000000002e-06\n",
  6160. "train: loss: 0.000145, bce: 0.000333, dice: 1.000640\n",
  6161. "val: loss: 0.000149, bce: 0.000363, dice: 1.001194\n",
  6162. "saving best model\n",
  6163. "0m 9s\n",
  6164. "\n",
  6165. "\n",
  6166. "Epoch 564/799\n",
  6167. "----------\n",
  6168. "LR 1.0000000000000002e-06\n",
  6169. "train: loss: 0.000145, bce: 0.000333, dice: 1.000640\n",
  6170. "val: loss: 0.000149, bce: 0.000362, dice: 1.001192\n",
  6171. "saving best model\n",
  6172. "0m 9s\n",
  6173. "\n",
  6174. "\n",
  6175. "Epoch 565/799\n",
  6176. "----------\n",
  6177. "LR 1.0000000000000002e-06\n",
  6178. "train: loss: 0.000145, bce: 0.000333, dice: 1.000641\n",
  6179. "val: loss: 0.000149, bce: 0.000362, dice: 1.001190\n",
  6180. "saving best model\n",
  6181. "0m 9s\n",
  6182. "\n",
  6183. "\n",
  6184. "Epoch 566/799\n",
  6185. "----------\n",
  6186. "LR 1.0000000000000002e-06\n",
  6187. "train: loss: 0.000145, bce: 0.000333, dice: 1.000639\n",
  6188. "val: loss: 0.000149, bce: 0.000362, dice: 1.001191\n",
  6189. "saving best model\n",
  6190. "0m 9s\n",
  6191. "\n",
  6192. "\n",
  6193. "Epoch 567/799\n",
  6194. "----------\n",
  6195. "LR 1.0000000000000002e-06\n",
  6196. "train: loss: 0.000145, bce: 0.000333, dice: 1.000640\n",
  6197. "val: loss: 0.000149, bce: 0.000362, dice: 1.001191\n",
  6198. "saving best model\n",
  6199. "0m 9s\n",
  6200. "\n",
  6201. "\n",
  6202. "Epoch 568/799\n",
  6203. "----------\n",
  6204. "LR 1.0000000000000002e-06\n",
  6205. "train: loss: 0.000145, bce: 0.000333, dice: 1.000640\n",
  6206. "val: loss: 0.000149, bce: 0.000362, dice: 1.001186\n",
  6207. "saving best model\n",
  6208. "0m 9s\n",
  6209. "\n",
  6210. "\n",
  6211. "Epoch 569/799\n",
  6212. "----------\n",
  6213. "LR 1.0000000000000002e-06\n",
  6214. "train: loss: 0.000145, bce: 0.000333, dice: 1.000640\n",
  6215. "val: loss: 0.000149, bce: 0.000362, dice: 1.001188\n",
  6216. "saving best model\n",
  6217. "0m 9s\n",
  6218. "\n",
  6219. "\n",
  6220. "Epoch 570/799\n",
  6221. "----------\n",
  6222. "LR 1.0000000000000002e-06\n",
  6223. "train: loss: 0.000145, bce: 0.000332, dice: 1.000639\n",
  6224. "val: loss: 0.000149, bce: 0.000362, dice: 1.001190\n",
  6225. "saving best model\n",
  6226. "0m 9s\n",
  6227. "\n",
  6228. "\n",
  6229. "Epoch 571/799\n",
  6230. "----------\n",
  6231. "LR 1.0000000000000002e-06\n",
  6232. "train: loss: 0.000145, bce: 0.000332, dice: 1.000640\n",
  6233. "val: loss: 0.000148, bce: 0.000362, dice: 1.001188\n",
  6234. "saving best model\n",
  6235. "0m 9s\n",
  6236. "\n",
  6237. "\n",
  6238. "Epoch 572/799\n",
  6239. "----------\n",
  6240. "LR 1.0000000000000002e-06\n",
  6241. "train: loss: 0.000145, bce: 0.000332, dice: 1.000639\n",
  6242. "val: loss: 0.000148, bce: 0.000362, dice: 1.001191\n",
  6243. "saving best model\n",
  6244. "0m 9s\n",
  6245. "\n",
  6246. "\n",
  6247. "Epoch 573/799\n",
  6248. "----------\n",
  6249. "LR 1.0000000000000002e-06\n",
  6250. "train: loss: 0.000145, bce: 0.000332, dice: 1.000639\n",
  6251. "val: loss: 0.000148, bce: 0.000362, dice: 1.001189\n",
  6252. "saving best model\n",
  6253. "0m 9s\n",
  6254. "\n",
  6255. "\n",
  6256. "Epoch 574/799\n",
  6257. "----------\n",
  6258. "LR 1.0000000000000002e-06\n",
  6259. "train: loss: 0.000145, bce: 0.000332, dice: 1.000639\n",
  6260. "val: loss: 0.000148, bce: 0.000361, dice: 1.001188\n",
  6261. "saving best model\n",
  6262. "0m 9s\n",
  6263. "\n",
  6264. "\n",
  6265. "Epoch 575/799\n",
  6266. "----------\n",
  6267. "LR 1.0000000000000002e-06\n",
  6268. "train: loss: 0.000145, bce: 0.000332, dice: 1.000638\n",
  6269. "val: loss: 0.000148, bce: 0.000361, dice: 1.001191\n",
  6270. "saving best model\n",
  6271. "0m 9s\n",
  6272. "\n",
  6273. "\n",
  6274. "Epoch 576/799\n",
  6275. "----------\n",
  6276. "LR 1.0000000000000002e-06\n",
  6277. "train: loss: 0.000145, bce: 0.000332, dice: 1.000639\n",
  6278. "val: loss: 0.000148, bce: 0.000361, dice: 1.001184\n",
  6279. "saving best model\n",
  6280. "0m 9s\n",
  6281. "\n",
  6282. "\n",
  6283. "Epoch 577/799\n",
  6284. "----------\n",
  6285. "LR 1.0000000000000002e-06\n",
  6286. "train: loss: 0.000144, bce: 0.000332, dice: 1.000638\n",
  6287. "val: loss: 0.000148, bce: 0.000361, dice: 1.001187\n",
  6288. "saving best model\n",
  6289. "0m 9s\n",
  6290. "\n",
  6291. "\n",
  6292. "Epoch 578/799\n",
  6293. "----------\n",
  6294. "LR 1.0000000000000002e-06\n",
  6295. "train: loss: 0.000144, bce: 0.000332, dice: 1.000638\n",
  6296. "val: loss: 0.000148, bce: 0.000361, dice: 1.001187\n",
  6297. "saving best model\n",
  6298. "0m 9s\n",
  6299. "\n",
  6300. "\n",
  6301. "Epoch 579/799\n",
  6302. "----------\n",
  6303. "LR 1.0000000000000002e-06\n",
  6304. "train: loss: 0.000144, bce: 0.000332, dice: 1.000639\n",
  6305. "val: loss: 0.000148, bce: 0.000361, dice: 1.001185\n",
  6306. "saving best model\n",
  6307. "0m 9s\n",
  6308. "\n",
  6309. "\n",
  6310. "Epoch 580/799\n",
  6311. "----------\n",
  6312. "LR 1.0000000000000002e-06\n",
  6313. "train: loss: 0.000144, bce: 0.000331, dice: 1.000637\n",
  6314. "val: loss: 0.000148, bce: 0.000361, dice: 1.001190\n",
  6315. "saving best model\n",
  6316. "0m 9s\n",
  6317. "\n",
  6318. "\n",
  6319. "Epoch 581/799\n",
  6320. "----------\n",
  6321. "LR 1.0000000000000002e-06\n",
  6322. "train: loss: 0.000144, bce: 0.000331, dice: 1.000639\n",
  6323. "val: loss: 0.000148, bce: 0.000361, dice: 1.001185\n",
  6324. "saving best model\n",
  6325. "0m 9s\n",
  6326. "\n",
  6327. "\n",
  6328. "Epoch 582/799\n",
  6329. "----------\n",
  6330. "LR 1.0000000000000002e-06\n",
  6331. "train: loss: 0.000144, bce: 0.000331, dice: 1.000638\n",
  6332. "val: loss: 0.000148, bce: 0.000361, dice: 1.001187\n",
  6333. "saving best model\n",
  6334. "0m 9s\n",
  6335. "\n",
  6336. "\n",
  6337. "Epoch 583/799\n",
  6338. "----------\n",
  6339. "LR 1.0000000000000002e-06\n",
  6340. "train: loss: 0.000144, bce: 0.000331, dice: 1.000637\n",
  6341. "val: loss: 0.000148, bce: 0.000361, dice: 1.001188\n",
  6342. "saving best model\n",
  6343. "0m 9s\n",
  6344. "\n",
  6345. "\n",
  6346. "Epoch 584/799\n",
  6347. "----------\n",
  6348. "LR 1.0000000000000002e-06\n",
  6349. "train: loss: 0.000144, bce: 0.000331, dice: 1.000638\n",
  6350. "val: loss: 0.000148, bce: 0.000360, dice: 1.001185\n",
  6351. "saving best model\n",
  6352. "0m 9s\n",
  6353. "\n",
  6354. "\n",
  6355. "Epoch 585/799\n",
  6356. "----------\n",
  6357. "LR 1.0000000000000002e-06\n",
  6358. "train: loss: 0.000144, bce: 0.000331, dice: 1.000638\n",
  6359. "val: loss: 0.000148, bce: 0.000360, dice: 1.001182\n",
  6360. "saving best model\n",
  6361. "0m 9s\n",
  6362. "\n",
  6363. "\n",
  6364. "Epoch 586/799\n",
  6365. "----------\n",
  6366. "LR 1.0000000000000002e-06\n",
  6367. "train: loss: 0.000144, bce: 0.000331, dice: 1.000636\n",
  6368. "val: loss: 0.000148, bce: 0.000360, dice: 1.001190\n",
  6369. "saving best model\n",
  6370. "0m 9s\n",
  6371. "\n",
  6372. "\n",
  6373. "Epoch 587/799\n",
  6374. "----------\n",
  6375. "LR 1.0000000000000002e-06\n",
  6376. "train: loss: 0.000144, bce: 0.000331, dice: 1.000638\n",
  6377. "val: loss: 0.000148, bce: 0.000360, dice: 1.001183\n",
  6378. "saving best model\n",
  6379. "0m 9s\n",
  6380. "\n",
  6381. "\n",
  6382. "Epoch 588/799\n",
  6383. "----------\n",
  6384. "LR 1.0000000000000002e-06\n",
  6385. "train: loss: 0.000144, bce: 0.000330, dice: 1.000637\n",
  6386. "val: loss: 0.000148, bce: 0.000360, dice: 1.001188\n",
  6387. "saving best model\n",
  6388. "0m 9s\n",
  6389. "\n",
  6390. "\n",
  6391. "Epoch 589/799\n",
  6392. "----------\n",
  6393. "LR 1.0000000000000002e-06\n",
  6394. "train: loss: 0.000144, bce: 0.000331, dice: 1.000637\n",
  6395. "val: loss: 0.000148, bce: 0.000360, dice: 1.001183\n",
  6396. "saving best model\n",
  6397. "0m 9s\n",
  6398. "\n",
  6399. "\n",
  6400. "Epoch 590/799\n",
  6401. "----------\n",
  6402. "LR 1.0000000000000002e-06\n",
  6403. "train: loss: 0.000144, bce: 0.000331, dice: 1.000637\n",
  6404. "val: loss: 0.000148, bce: 0.000359, dice: 1.001182\n",
  6405. "saving best model\n",
  6406. "0m 9s\n",
  6407. "\n",
  6408. "\n",
  6409. "Epoch 591/799\n",
  6410. "----------\n",
  6411. "LR 1.0000000000000002e-06\n",
  6412. "train: loss: 0.000144, bce: 0.000331, dice: 1.000637\n",
  6413. "val: loss: 0.000148, bce: 0.000359, dice: 1.001181\n",
  6414. "saving best model\n",
  6415. "0m 9s\n",
  6416. "\n",
  6417. "\n",
  6418. "Epoch 592/799\n",
  6419. "----------\n",
  6420. "LR 1.0000000000000002e-06\n",
  6421. "train: loss: 0.000144, bce: 0.000330, dice: 1.000637\n",
  6422. "val: loss: 0.000148, bce: 0.000359, dice: 1.001179\n",
  6423. "saving best model\n",
  6424. "0m 9s\n",
  6425. "\n",
  6426. "\n",
  6427. "Epoch 593/799\n",
  6428. "----------\n",
  6429. "LR 1.0000000000000002e-06\n",
  6430. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6431. "val: loss: 0.000148, bce: 0.000359, dice: 1.001184\n",
  6432. "saving best model\n",
  6433. "0m 9s\n",
  6434. "\n",
  6435. "\n",
  6436. "Epoch 594/799\n",
  6437. "----------\n",
  6438. "LR 1.0000000000000002e-06\n",
  6439. "train: loss: 0.000144, bce: 0.000330, dice: 1.000637\n",
  6440. "val: loss: 0.000148, bce: 0.000359, dice: 1.001177\n",
  6441. "0m 9s\n",
  6442. "\n",
  6443. "\n",
  6444. "Epoch 595/799\n",
  6445. "----------\n",
  6446. "LR 1.0000000000000002e-06\n",
  6447. "train: loss: 0.000144, bce: 0.000330, dice: 1.000637\n",
  6448. "val: loss: 0.000147, bce: 0.000359, dice: 1.001182\n",
  6449. "saving best model\n",
  6450. "0m 9s\n",
  6451. "\n",
  6452. "\n",
  6453. "Epoch 596/799\n",
  6454. "----------\n",
  6455. "LR 1.0000000000000002e-06\n",
  6456. "train: loss: 0.000144, bce: 0.000330, dice: 1.000637\n",
  6457. "val: loss: 0.000147, bce: 0.000359, dice: 1.001179\n",
  6458. "saving best model\n",
  6459. "0m 9s\n",
  6460. "\n",
  6461. "\n",
  6462. "Epoch 597/799\n",
  6463. "----------\n",
  6464. "LR 1.0000000000000002e-06\n",
  6465. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6466. "val: loss: 0.000147, bce: 0.000359, dice: 1.001184\n",
  6467. "saving best model\n",
  6468. "0m 9s\n",
  6469. "\n",
  6470. "\n",
  6471. "Epoch 598/799\n",
  6472. "----------\n",
  6473. "LR 1.0000000000000002e-06\n",
  6474. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6475. "val: loss: 0.000147, bce: 0.000359, dice: 1.001180\n",
  6476. "saving best model\n",
  6477. "0m 9s\n",
  6478. "\n",
  6479. "\n",
  6480. "Epoch 599/799\n",
  6481. "----------\n",
  6482. "LR 1.0000000000000002e-07\n",
  6483. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6484. "val: loss: 0.000147, bce: 0.000359, dice: 1.001180\n",
  6485. "saving best model\n",
  6486. "0m 9s\n",
  6487. "\n",
  6488. "\n",
  6489. "Epoch 600/799\n",
  6490. "----------\n",
  6491. "LR 1.0000000000000002e-07\n",
  6492. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6493. "val: loss: 0.000147, bce: 0.000359, dice: 1.001180\n",
  6494. "saving best model\n",
  6495. "0m 9s\n",
  6496. "\n",
  6497. "\n",
  6498. "Epoch 601/799\n",
  6499. "----------\n",
  6500. "LR 1.0000000000000002e-07\n",
  6501. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6502. "val: loss: 0.000147, bce: 0.000359, dice: 1.001180\n",
  6503. "saving best model\n",
  6504. "0m 9s\n",
  6505. "\n",
  6506. "\n",
  6507. "Epoch 602/799\n",
  6508. "----------\n",
  6509. "LR 1.0000000000000002e-07\n",
  6510. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6511. "val: loss: 0.000147, bce: 0.000359, dice: 1.001180\n",
  6512. "saving best model\n",
  6513. "0m 9s\n",
  6514. "\n",
  6515. "\n",
  6516. "Epoch 603/799\n",
  6517. "----------\n",
  6518. "LR 1.0000000000000002e-07\n",
  6519. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6520. "val: loss: 0.000147, bce: 0.000359, dice: 1.001180\n",
  6521. "saving best model\n",
  6522. "0m 9s\n",
  6523. "\n",
  6524. "\n",
  6525. "Epoch 604/799\n",
  6526. "----------\n",
  6527. "LR 1.0000000000000002e-07\n",
  6528. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6529. "val: loss: 0.000147, bce: 0.000359, dice: 1.001180\n",
  6530. "saving best model\n",
  6531. "0m 9s\n",
  6532. "\n",
  6533. "\n",
  6534. "Epoch 605/799\n",
  6535. "----------\n",
  6536. "LR 1.0000000000000002e-07\n",
  6537. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6538. "val: loss: 0.000147, bce: 0.000359, dice: 1.001180\n",
  6539. "saving best model\n",
  6540. "0m 9s\n",
  6541. "\n",
  6542. "\n",
  6543. "Epoch 606/799\n",
  6544. "----------\n",
  6545. "LR 1.0000000000000002e-07\n",
  6546. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6547. "val: loss: 0.000147, bce: 0.000359, dice: 1.001180\n",
  6548. "saving best model\n",
  6549. "0m 9s\n",
  6550. "\n",
  6551. "\n",
  6552. "Epoch 607/799\n",
  6553. "----------\n",
  6554. "LR 1.0000000000000002e-07\n",
  6555. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6556. "val: loss: 0.000147, bce: 0.000359, dice: 1.001180\n",
  6557. "saving best model\n",
  6558. "0m 9s\n",
  6559. "\n",
  6560. "\n",
  6561. "Epoch 608/799\n",
  6562. "----------\n",
  6563. "LR 1.0000000000000002e-07\n",
  6564. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6565. "val: loss: 0.000147, bce: 0.000359, dice: 1.001180\n",
  6566. "saving best model\n",
  6567. "0m 9s\n",
  6568. "\n",
  6569. "\n",
  6570. "Epoch 609/799\n",
  6571. "----------\n",
  6572. "LR 1.0000000000000002e-07\n",
  6573. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6574. "val: loss: 0.000147, bce: 0.000359, dice: 1.001180\n",
  6575. "saving best model\n",
  6576. "0m 9s\n",
  6577. "\n",
  6578. "\n",
  6579. "Epoch 610/799\n",
  6580. "----------\n",
  6581. "LR 1.0000000000000002e-07\n",
  6582. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6583. "val: loss: 0.000147, bce: 0.000358, dice: 1.001180\n",
  6584. "saving best model\n",
  6585. "0m 9s\n",
  6586. "\n",
  6587. "\n",
  6588. "Epoch 611/799\n",
  6589. "----------\n",
  6590. "LR 1.0000000000000002e-07\n",
  6591. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6592. "val: loss: 0.000147, bce: 0.000358, dice: 1.001180\n",
  6593. "saving best model\n",
  6594. "0m 9s\n",
  6595. "\n",
  6596. "\n",
  6597. "Epoch 612/799\n",
  6598. "----------\n",
  6599. "LR 1.0000000000000002e-07\n",
  6600. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6601. "val: loss: 0.000147, bce: 0.000358, dice: 1.001180\n",
  6602. "saving best model\n",
  6603. "0m 9s\n",
  6604. "\n",
  6605. "\n",
  6606. "Epoch 613/799\n",
  6607. "----------\n",
  6608. "LR 1.0000000000000002e-07\n",
  6609. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6610. "val: loss: 0.000147, bce: 0.000358, dice: 1.001180\n",
  6611. "saving best model\n",
  6612. "0m 9s\n",
  6613. "\n",
  6614. "\n",
  6615. "Epoch 614/799\n",
  6616. "----------\n",
  6617. "LR 1.0000000000000002e-07\n",
  6618. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6619. "val: loss: 0.000147, bce: 0.000358, dice: 1.001180\n",
  6620. "saving best model\n",
  6621. "0m 9s\n",
  6622. "\n",
  6623. "\n",
  6624. "Epoch 615/799\n",
  6625. "----------\n",
  6626. "LR 1.0000000000000002e-07\n",
  6627. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6628. "val: loss: 0.000147, bce: 0.000358, dice: 1.001180\n",
  6629. "saving best model\n",
  6630. "0m 9s\n",
  6631. "\n",
  6632. "\n",
  6633. "Epoch 616/799\n",
  6634. "----------\n",
  6635. "LR 1.0000000000000002e-07\n",
  6636. "train: loss: 0.000144, bce: 0.000330, dice: 1.000636\n",
  6637. "val: loss: 0.000147, bce: 0.000358, dice: 1.001180\n",
  6638. "saving best model\n",
  6639. "0m 9s\n",
  6640. "\n",
  6641. "\n",
  6642. "Epoch 617/799\n",
  6643. "----------\n",
  6644. "LR 1.0000000000000002e-07\n",
  6645. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6646. "val: loss: 0.000147, bce: 0.000358, dice: 1.001180\n",
  6647. "saving best model\n",
  6648. "0m 9s\n",
  6649. "\n",
  6650. "\n",
  6651. "Epoch 618/799\n",
  6652. "----------\n",
  6653. "LR 1.0000000000000002e-07\n",
  6654. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6655. "val: loss: 0.000147, bce: 0.000358, dice: 1.001180\n",
  6656. "saving best model\n",
  6657. "0m 9s\n",
  6658. "\n",
  6659. "\n",
  6660. "Epoch 619/799\n",
  6661. "----------\n",
  6662. "LR 1.0000000000000002e-07\n",
  6663. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6664. "val: loss: 0.000147, bce: 0.000358, dice: 1.001180\n",
  6665. "saving best model\n",
  6666. "0m 9s\n",
  6667. "\n",
  6668. "\n",
  6669. "Epoch 620/799\n",
  6670. "----------\n",
  6671. "LR 1.0000000000000002e-07\n",
  6672. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6673. "val: loss: 0.000147, bce: 0.000358, dice: 1.001180\n",
  6674. "saving best model\n",
  6675. "0m 9s\n",
  6676. "\n",
  6677. "\n",
  6678. "Epoch 621/799\n",
  6679. "----------\n",
  6680. "LR 1.0000000000000002e-07\n",
  6681. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6682. "val: loss: 0.000147, bce: 0.000358, dice: 1.001180\n",
  6683. "saving best model\n",
  6684. "0m 9s\n",
  6685. "\n",
  6686. "\n",
  6687. "Epoch 622/799\n",
  6688. "----------\n",
  6689. "LR 1.0000000000000002e-07\n",
  6690. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6691. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6692. "saving best model\n",
  6693. "0m 9s\n",
  6694. "\n",
  6695. "\n",
  6696. "Epoch 623/799\n",
  6697. "----------\n",
  6698. "LR 1.0000000000000002e-07\n",
  6699. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6700. "val: loss: 0.000147, bce: 0.000358, dice: 1.001180\n",
  6701. "saving best model\n",
  6702. "0m 9s\n",
  6703. "\n",
  6704. "\n",
  6705. "Epoch 624/799\n",
  6706. "----------\n",
  6707. "LR 1.0000000000000002e-07\n",
  6708. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6709. "val: loss: 0.000147, bce: 0.000358, dice: 1.001180\n",
  6710. "saving best model\n",
  6711. "0m 9s\n",
  6712. "\n",
  6713. "\n",
  6714. "Epoch 625/799\n",
  6715. "----------\n",
  6716. "LR 1.0000000000000002e-07\n",
  6717. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6718. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6719. "saving best model\n",
  6720. "0m 9s\n",
  6721. "\n",
  6722. "\n",
  6723. "Epoch 626/799\n",
  6724. "----------\n",
  6725. "LR 1.0000000000000002e-07\n",
  6726. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6727. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6728. "saving best model\n",
  6729. "0m 9s\n",
  6730. "\n",
  6731. "\n",
  6732. "Epoch 627/799\n",
  6733. "----------\n",
  6734. "LR 1.0000000000000002e-07\n",
  6735. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6736. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6737. "saving best model\n",
  6738. "0m 9s\n",
  6739. "\n",
  6740. "\n",
  6741. "Epoch 628/799\n",
  6742. "----------\n",
  6743. "LR 1.0000000000000002e-07\n",
  6744. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6745. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6746. "saving best model\n",
  6747. "0m 9s\n",
  6748. "\n",
  6749. "\n",
  6750. "Epoch 629/799\n",
  6751. "----------\n",
  6752. "LR 1.0000000000000002e-07\n",
  6753. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6754. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6755. "saving best model\n",
  6756. "0m 9s\n",
  6757. "\n",
  6758. "\n",
  6759. "Epoch 630/799\n",
  6760. "----------\n",
  6761. "LR 1.0000000000000002e-07\n",
  6762. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6763. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6764. "saving best model\n",
  6765. "0m 9s\n",
  6766. "\n",
  6767. "\n",
  6768. "Epoch 631/799\n",
  6769. "----------\n",
  6770. "LR 1.0000000000000002e-07\n",
  6771. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6772. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6773. "saving best model\n",
  6774. "0m 9s\n",
  6775. "\n",
  6776. "\n",
  6777. "Epoch 632/799\n",
  6778. "----------\n",
  6779. "LR 1.0000000000000002e-07\n",
  6780. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6781. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6782. "saving best model\n",
  6783. "0m 9s\n",
  6784. "\n",
  6785. "\n",
  6786. "Epoch 633/799\n",
  6787. "----------\n",
  6788. "LR 1.0000000000000002e-07\n",
  6789. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6790. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6791. "saving best model\n",
  6792. "0m 9s\n",
  6793. "\n",
  6794. "\n",
  6795. "Epoch 634/799\n",
  6796. "----------\n",
  6797. "LR 1.0000000000000002e-07\n",
  6798. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6799. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6800. "saving best model\n",
  6801. "0m 9s\n",
  6802. "\n",
  6803. "\n",
  6804. "Epoch 635/799\n",
  6805. "----------\n",
  6806. "LR 1.0000000000000002e-07\n",
  6807. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6808. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6809. "saving best model\n",
  6810. "0m 9s\n",
  6811. "\n",
  6812. "\n",
  6813. "Epoch 636/799\n",
  6814. "----------\n",
  6815. "LR 1.0000000000000002e-07\n",
  6816. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6817. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6818. "saving best model\n",
  6819. "0m 9s\n",
  6820. "\n",
  6821. "\n",
  6822. "Epoch 637/799\n",
  6823. "----------\n",
  6824. "LR 1.0000000000000002e-07\n",
  6825. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6826. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6827. "saving best model\n",
  6828. "0m 9s\n",
  6829. "\n",
  6830. "\n",
  6831. "Epoch 638/799\n",
  6832. "----------\n",
  6833. "LR 1.0000000000000002e-07\n",
  6834. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6835. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6836. "saving best model\n",
  6837. "0m 9s\n",
  6838. "\n",
  6839. "\n",
  6840. "Epoch 639/799\n",
  6841. "----------\n",
  6842. "LR 1.0000000000000002e-07\n",
  6843. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6844. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6845. "saving best model\n",
  6846. "0m 9s\n",
  6847. "\n",
  6848. "\n",
  6849. "Epoch 640/799\n",
  6850. "----------\n",
  6851. "LR 1.0000000000000002e-07\n",
  6852. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6853. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6854. "saving best model\n",
  6855. "0m 9s\n",
  6856. "\n",
  6857. "\n",
  6858. "Epoch 641/799\n",
  6859. "----------\n",
  6860. "LR 1.0000000000000002e-07\n",
  6861. "train: loss: 0.000144, bce: 0.000329, dice: 1.000635\n",
  6862. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6863. "saving best model\n",
  6864. "0m 9s\n",
  6865. "\n",
  6866. "\n",
  6867. "Epoch 642/799\n",
  6868. "----------\n",
  6869. "LR 1.0000000000000002e-07\n",
  6870. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6871. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6872. "saving best model\n",
  6873. "0m 9s\n",
  6874. "\n",
  6875. "\n",
  6876. "Epoch 643/799\n",
  6877. "----------\n",
  6878. "LR 1.0000000000000002e-07\n",
  6879. "train: loss: 0.000144, bce: 0.000329, dice: 1.000635\n",
  6880. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6881. "saving best model\n",
  6882. "0m 9s\n",
  6883. "\n",
  6884. "\n",
  6885. "Epoch 644/799\n",
  6886. "----------\n",
  6887. "LR 1.0000000000000002e-07\n",
  6888. "train: loss: 0.000144, bce: 0.000329, dice: 1.000635\n",
  6889. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6890. "saving best model\n",
  6891. "0m 9s\n",
  6892. "\n",
  6893. "\n",
  6894. "Epoch 645/799\n",
  6895. "----------\n",
  6896. "LR 1.0000000000000002e-07\n",
  6897. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6898. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6899. "saving best model\n",
  6900. "0m 9s\n",
  6901. "\n",
  6902. "\n",
  6903. "Epoch 646/799\n",
  6904. "----------\n",
  6905. "LR 1.0000000000000002e-07\n",
  6906. "train: loss: 0.000144, bce: 0.000329, dice: 1.000635\n",
  6907. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6908. "saving best model\n",
  6909. "0m 9s\n",
  6910. "\n",
  6911. "\n",
  6912. "Epoch 647/799\n",
  6913. "----------\n",
  6914. "LR 1.0000000000000002e-07\n",
  6915. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6916. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6917. "saving best model\n",
  6918. "0m 9s\n",
  6919. "\n",
  6920. "\n",
  6921. "Epoch 648/799\n",
  6922. "----------\n",
  6923. "LR 1.0000000000000002e-07\n",
  6924. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6925. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6926. "saving best model\n",
  6927. "0m 9s\n",
  6928. "\n",
  6929. "\n",
  6930. "Epoch 649/799\n",
  6931. "----------\n",
  6932. "LR 1.0000000000000002e-07\n",
  6933. "train: loss: 0.000144, bce: 0.000329, dice: 1.000636\n",
  6934. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6935. "saving best model\n",
  6936. "0m 9s\n",
  6937. "\n",
  6938. "\n",
  6939. "Epoch 650/799\n",
  6940. "----------\n",
  6941. "LR 1.0000000000000002e-07\n",
  6942. "train: loss: 0.000144, bce: 0.000329, dice: 1.000635\n",
  6943. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6944. "saving best model\n",
  6945. "0m 9s\n",
  6946. "\n",
  6947. "\n",
  6948. "Epoch 651/799\n",
  6949. "----------\n",
  6950. "LR 1.0000000000000002e-07\n",
  6951. "train: loss: 0.000144, bce: 0.000329, dice: 1.000635\n",
  6952. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6953. "saving best model\n",
  6954. "0m 9s\n",
  6955. "\n",
  6956. "\n",
  6957. "Epoch 652/799\n",
  6958. "----------\n",
  6959. "LR 1.0000000000000002e-07\n",
  6960. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  6961. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6962. "saving best model\n",
  6963. "0m 9s\n",
  6964. "\n",
  6965. "\n",
  6966. "Epoch 653/799\n",
  6967. "----------\n",
  6968. "LR 1.0000000000000002e-07\n",
  6969. "train: loss: 0.000143, bce: 0.000329, dice: 1.000636\n",
  6970. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6971. "saving best model\n",
  6972. "0m 9s\n",
  6973. "\n",
  6974. "\n",
  6975. "Epoch 654/799\n",
  6976. "----------\n",
  6977. "LR 1.0000000000000002e-07\n",
  6978. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  6979. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6980. "saving best model\n",
  6981. "0m 9s\n",
  6982. "\n",
  6983. "\n",
  6984. "Epoch 655/799\n",
  6985. "----------\n",
  6986. "LR 1.0000000000000002e-07\n",
  6987. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  6988. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6989. "saving best model\n",
  6990. "0m 9s\n",
  6991. "\n",
  6992. "\n",
  6993. "Epoch 656/799\n",
  6994. "----------\n",
  6995. "LR 1.0000000000000002e-07\n",
  6996. "train: loss: 0.000143, bce: 0.000329, dice: 1.000636\n",
  6997. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  6998. "saving best model\n",
  6999. "0m 9s\n",
  7000. "\n",
  7001. "\n",
  7002. "Epoch 657/799\n",
  7003. "----------\n",
  7004. "LR 1.0000000000000002e-07\n",
  7005. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7006. "val: loss: 0.000147, bce: 0.000358, dice: 1.001179\n",
  7007. "saving best model\n",
  7008. "0m 9s\n",
  7009. "\n",
  7010. "\n",
  7011. "Epoch 658/799\n",
  7012. "----------\n",
  7013. "LR 1.0000000000000002e-07\n",
  7014. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7015. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7016. "saving best model\n",
  7017. "0m 9s\n",
  7018. "\n",
  7019. "\n",
  7020. "Epoch 659/799\n",
  7021. "----------\n",
  7022. "LR 1.0000000000000002e-07\n",
  7023. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7024. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7025. "saving best model\n",
  7026. "0m 9s\n",
  7027. "\n",
  7028. "\n",
  7029. "Epoch 660/799\n",
  7030. "----------\n",
  7031. "LR 1.0000000000000002e-07\n",
  7032. "train: loss: 0.000143, bce: 0.000329, dice: 1.000636\n",
  7033. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7034. "saving best model\n",
  7035. "0m 9s\n",
  7036. "\n",
  7037. "\n",
  7038. "Epoch 661/799\n",
  7039. "----------\n",
  7040. "LR 1.0000000000000002e-07\n",
  7041. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7042. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7043. "saving best model\n",
  7044. "0m 9s\n",
  7045. "\n",
  7046. "\n",
  7047. "Epoch 662/799\n",
  7048. "----------\n",
  7049. "LR 1.0000000000000002e-07\n",
  7050. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7051. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7052. "saving best model\n",
  7053. "0m 9s\n",
  7054. "\n",
  7055. "\n",
  7056. "Epoch 663/799\n",
  7057. "----------\n",
  7058. "LR 1.0000000000000002e-07\n",
  7059. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7060. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7061. "saving best model\n",
  7062. "0m 9s\n",
  7063. "\n",
  7064. "\n",
  7065. "Epoch 664/799\n",
  7066. "----------\n",
  7067. "LR 1.0000000000000002e-07\n",
  7068. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7069. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7070. "saving best model\n",
  7071. "0m 9s\n",
  7072. "\n",
  7073. "\n",
  7074. "Epoch 665/799\n",
  7075. "----------\n",
  7076. "LR 1.0000000000000002e-07\n",
  7077. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7078. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7079. "saving best model\n",
  7080. "0m 9s\n",
  7081. "\n",
  7082. "\n",
  7083. "Epoch 666/799\n",
  7084. "----------\n",
  7085. "LR 1.0000000000000002e-07\n",
  7086. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7087. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7088. "saving best model\n",
  7089. "0m 9s\n",
  7090. "\n",
  7091. "\n",
  7092. "Epoch 667/799\n",
  7093. "----------\n",
  7094. "LR 1.0000000000000002e-07\n",
  7095. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7096. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7097. "saving best model\n",
  7098. "0m 9s\n",
  7099. "\n",
  7100. "\n",
  7101. "Epoch 668/799\n",
  7102. "----------\n",
  7103. "LR 1.0000000000000002e-07\n",
  7104. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7105. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7106. "saving best model\n",
  7107. "0m 9s\n",
  7108. "\n",
  7109. "\n",
  7110. "Epoch 669/799\n",
  7111. "----------\n",
  7112. "LR 1.0000000000000002e-07\n",
  7113. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7114. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7115. "saving best model\n",
  7116. "0m 9s\n",
  7117. "\n",
  7118. "\n",
  7119. "Epoch 670/799\n",
  7120. "----------\n",
  7121. "LR 1.0000000000000002e-07\n",
  7122. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7123. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7124. "saving best model\n",
  7125. "0m 9s\n",
  7126. "\n",
  7127. "\n",
  7128. "Epoch 671/799\n",
  7129. "----------\n",
  7130. "LR 1.0000000000000002e-07\n",
  7131. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7132. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7133. "saving best model\n",
  7134. "0m 9s\n",
  7135. "\n",
  7136. "\n",
  7137. "Epoch 672/799\n",
  7138. "----------\n",
  7139. "LR 1.0000000000000002e-07\n",
  7140. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7141. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7142. "saving best model\n",
  7143. "0m 9s\n",
  7144. "\n",
  7145. "\n",
  7146. "Epoch 673/799\n",
  7147. "----------\n",
  7148. "LR 1.0000000000000002e-07\n",
  7149. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7150. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7151. "saving best model\n",
  7152. "0m 9s\n",
  7153. "\n",
  7154. "\n",
  7155. "Epoch 674/799\n",
  7156. "----------\n",
  7157. "LR 1.0000000000000002e-07\n",
  7158. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7159. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7160. "saving best model\n",
  7161. "0m 9s\n",
  7162. "\n",
  7163. "\n",
  7164. "Epoch 675/799\n",
  7165. "----------\n",
  7166. "LR 1.0000000000000002e-07\n",
  7167. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7168. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7169. "saving best model\n",
  7170. "0m 9s\n",
  7171. "\n",
  7172. "\n",
  7173. "Epoch 676/799\n",
  7174. "----------\n",
  7175. "LR 1.0000000000000002e-07\n",
  7176. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7177. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7178. "saving best model\n",
  7179. "0m 9s\n",
  7180. "\n",
  7181. "\n",
  7182. "Epoch 677/799\n",
  7183. "----------\n",
  7184. "LR 1.0000000000000002e-07\n",
  7185. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7186. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7187. "saving best model\n",
  7188. "0m 9s\n",
  7189. "\n",
  7190. "\n",
  7191. "Epoch 678/799\n",
  7192. "----------\n",
  7193. "LR 1.0000000000000002e-07\n",
  7194. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7195. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7196. "saving best model\n",
  7197. "0m 9s\n",
  7198. "\n",
  7199. "\n",
  7200. "Epoch 679/799\n",
  7201. "----------\n",
  7202. "LR 1.0000000000000002e-07\n",
  7203. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7204. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7205. "saving best model\n",
  7206. "0m 9s\n",
  7207. "\n",
  7208. "\n",
  7209. "Epoch 680/799\n",
  7210. "----------\n",
  7211. "LR 1.0000000000000002e-07\n",
  7212. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7213. "val: loss: 0.000147, bce: 0.000358, dice: 1.001178\n",
  7214. "saving best model\n",
  7215. "0m 9s\n",
  7216. "\n",
  7217. "\n",
  7218. "Epoch 681/799\n",
  7219. "----------\n",
  7220. "LR 1.0000000000000002e-07\n",
  7221. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7222. "val: loss: 0.000147, bce: 0.000358, dice: 1.001177\n",
  7223. "saving best model\n",
  7224. "0m 9s\n",
  7225. "\n",
  7226. "\n",
  7227. "Epoch 682/799\n",
  7228. "----------\n",
  7229. "LR 1.0000000000000002e-07\n",
  7230. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7231. "val: loss: 0.000147, bce: 0.000358, dice: 1.001177\n",
  7232. "saving best model\n",
  7233. "0m 9s\n",
  7234. "\n",
  7235. "\n",
  7236. "Epoch 683/799\n",
  7237. "----------\n",
  7238. "LR 1.0000000000000002e-07\n",
  7239. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7240. "val: loss: 0.000147, bce: 0.000358, dice: 1.001177\n",
  7241. "saving best model\n",
  7242. "0m 9s\n",
  7243. "\n",
  7244. "\n",
  7245. "Epoch 684/799\n",
  7246. "----------\n",
  7247. "LR 1.0000000000000002e-07\n",
  7248. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7249. "val: loss: 0.000147, bce: 0.000358, dice: 1.001177\n",
  7250. "saving best model\n",
  7251. "0m 9s\n",
  7252. "\n",
  7253. "\n",
  7254. "Epoch 685/799\n",
  7255. "----------\n",
  7256. "LR 1.0000000000000002e-07\n",
  7257. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7258. "val: loss: 0.000147, bce: 0.000358, dice: 1.001177\n",
  7259. "saving best model\n",
  7260. "0m 9s\n",
  7261. "\n",
  7262. "\n",
  7263. "Epoch 686/799\n",
  7264. "----------\n",
  7265. "LR 1.0000000000000002e-07\n",
  7266. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7267. "val: loss: 0.000147, bce: 0.000357, dice: 1.001177\n",
  7268. "saving best model\n",
  7269. "0m 9s\n",
  7270. "\n",
  7271. "\n",
  7272. "Epoch 687/799\n",
  7273. "----------\n",
  7274. "LR 1.0000000000000002e-07\n",
  7275. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7276. "val: loss: 0.000147, bce: 0.000357, dice: 1.001177\n",
  7277. "saving best model\n",
  7278. "0m 9s\n",
  7279. "\n",
  7280. "\n",
  7281. "Epoch 688/799\n",
  7282. "----------\n",
  7283. "LR 1.0000000000000002e-07\n",
  7284. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7285. "val: loss: 0.000147, bce: 0.000357, dice: 1.001177\n",
  7286. "saving best model\n",
  7287. "0m 9s\n",
  7288. "\n",
  7289. "\n",
  7290. "Epoch 689/799\n",
  7291. "----------\n",
  7292. "LR 1.0000000000000002e-07\n",
  7293. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7294. "val: loss: 0.000147, bce: 0.000357, dice: 1.001177\n",
  7295. "saving best model\n",
  7296. "0m 9s\n",
  7297. "\n",
  7298. "\n",
  7299. "Epoch 690/799\n",
  7300. "----------\n",
  7301. "LR 1.0000000000000002e-07\n",
  7302. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7303. "val: loss: 0.000147, bce: 0.000357, dice: 1.001177\n",
  7304. "saving best model\n",
  7305. "0m 9s\n",
  7306. "\n",
  7307. "\n",
  7308. "Epoch 691/799\n",
  7309. "----------\n",
  7310. "LR 1.0000000000000002e-07\n",
  7311. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7312. "val: loss: 0.000147, bce: 0.000357, dice: 1.001177\n",
  7313. "saving best model\n",
  7314. "0m 9s\n",
  7315. "\n",
  7316. "\n",
  7317. "Epoch 692/799\n",
  7318. "----------\n",
  7319. "LR 1.0000000000000002e-07\n",
  7320. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7321. "val: loss: 0.000147, bce: 0.000357, dice: 1.001177\n",
  7322. "saving best model\n",
  7323. "0m 9s\n",
  7324. "\n",
  7325. "\n",
  7326. "Epoch 693/799\n",
  7327. "----------\n",
  7328. "LR 1.0000000000000002e-07\n",
  7329. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7330. "val: loss: 0.000147, bce: 0.000357, dice: 1.001177\n",
  7331. "saving best model\n",
  7332. "0m 9s\n",
  7333. "\n",
  7334. "\n",
  7335. "Epoch 694/799\n",
  7336. "----------\n",
  7337. "LR 1.0000000000000002e-07\n",
  7338. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7339. "val: loss: 0.000147, bce: 0.000357, dice: 1.001177\n",
  7340. "saving best model\n",
  7341. "0m 9s\n",
  7342. "\n",
  7343. "\n",
  7344. "Epoch 695/799\n",
  7345. "----------\n",
  7346. "LR 1.0000000000000002e-07\n",
  7347. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7348. "val: loss: 0.000147, bce: 0.000357, dice: 1.001177\n",
  7349. "saving best model\n",
  7350. "0m 9s\n",
  7351. "\n",
  7352. "\n",
  7353. "Epoch 696/799\n",
  7354. "----------\n",
  7355. "LR 1.0000000000000002e-07\n",
  7356. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7357. "val: loss: 0.000147, bce: 0.000357, dice: 1.001177\n",
  7358. "saving best model\n",
  7359. "0m 9s\n",
  7360. "\n",
  7361. "\n",
  7362. "Epoch 697/799\n",
  7363. "----------\n",
  7364. "LR 1.0000000000000002e-07\n",
  7365. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7366. "val: loss: 0.000147, bce: 0.000357, dice: 1.001177\n",
  7367. "saving best model\n",
  7368. "0m 9s\n",
  7369. "\n",
  7370. "\n",
  7371. "Epoch 698/799\n",
  7372. "----------\n",
  7373. "LR 1.0000000000000002e-07\n",
  7374. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7375. "val: loss: 0.000147, bce: 0.000357, dice: 1.001177\n",
  7376. "saving best model\n",
  7377. "0m 9s\n",
  7378. "\n",
  7379. "\n",
  7380. "Epoch 699/799\n",
  7381. "----------\n",
  7382. "LR 1.0000000000000002e-07\n",
  7383. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7384. "val: loss: 0.000147, bce: 0.000357, dice: 1.001177\n",
  7385. "saving best model\n",
  7386. "0m 9s\n",
  7387. "\n",
  7388. "\n",
  7389. "Epoch 700/799\n",
  7390. "----------\n",
  7391. "LR 1.0000000000000002e-07\n",
  7392. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7393. "val: loss: 0.000147, bce: 0.000357, dice: 1.001177\n",
  7394. "saving best model\n",
  7395. "0m 9s\n",
  7396. "\n",
  7397. "\n",
  7398. "Epoch 701/799\n",
  7399. "----------\n",
  7400. "LR 1.0000000000000002e-07\n",
  7401. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7402. "val: loss: 0.000147, bce: 0.000357, dice: 1.001177\n",
  7403. "saving best model\n",
  7404. "0m 9s\n",
  7405. "\n",
  7406. "\n",
  7407. "Epoch 702/799\n",
  7408. "----------\n",
  7409. "LR 1.0000000000000002e-07\n",
  7410. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7411. "val: loss: 0.000147, bce: 0.000357, dice: 1.001177\n",
  7412. "saving best model\n",
  7413. "0m 9s\n",
  7414. "\n",
  7415. "\n",
  7416. "Epoch 703/799\n",
  7417. "----------\n",
  7418. "LR 1.0000000000000002e-07\n",
  7419. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7420. "val: loss: 0.000147, bce: 0.000357, dice: 1.001177\n",
  7421. "saving best model\n",
  7422. "0m 9s\n",
  7423. "\n",
  7424. "\n",
  7425. "Epoch 704/799\n",
  7426. "----------\n",
  7427. "LR 1.0000000000000002e-07\n",
  7428. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7429. "val: loss: 0.000147, bce: 0.000357, dice: 1.001177\n",
  7430. "saving best model\n",
  7431. "0m 9s\n",
  7432. "\n",
  7433. "\n",
  7434. "Epoch 705/799\n",
  7435. "----------\n",
  7436. "LR 1.0000000000000002e-07\n",
  7437. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7438. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7439. "saving best model\n",
  7440. "0m 9s\n",
  7441. "\n",
  7442. "\n",
  7443. "Epoch 706/799\n",
  7444. "----------\n",
  7445. "LR 1.0000000000000002e-07\n",
  7446. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7447. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7448. "saving best model\n",
  7449. "0m 9s\n",
  7450. "\n",
  7451. "\n",
  7452. "Epoch 707/799\n",
  7453. "----------\n",
  7454. "LR 1.0000000000000002e-07\n",
  7455. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7456. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7457. "saving best model\n",
  7458. "0m 9s\n",
  7459. "\n",
  7460. "\n",
  7461. "Epoch 708/799\n",
  7462. "----------\n",
  7463. "LR 1.0000000000000002e-07\n",
  7464. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7465. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7466. "saving best model\n",
  7467. "0m 9s\n",
  7468. "\n",
  7469. "\n",
  7470. "Epoch 709/799\n",
  7471. "----------\n",
  7472. "LR 1.0000000000000002e-07\n",
  7473. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7474. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7475. "saving best model\n",
  7476. "0m 9s\n",
  7477. "\n",
  7478. "\n",
  7479. "Epoch 710/799\n",
  7480. "----------\n",
  7481. "LR 1.0000000000000002e-07\n",
  7482. "train: loss: 0.000143, bce: 0.000329, dice: 1.000635\n",
  7483. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7484. "saving best model\n",
  7485. "0m 9s\n",
  7486. "\n",
  7487. "\n",
  7488. "Epoch 711/799\n",
  7489. "----------\n",
  7490. "LR 1.0000000000000002e-07\n",
  7491. "train: loss: 0.000143, bce: 0.000328, dice: 1.000635\n",
  7492. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7493. "saving best model\n",
  7494. "0m 9s\n",
  7495. "\n",
  7496. "\n",
  7497. "Epoch 712/799\n",
  7498. "----------\n",
  7499. "LR 1.0000000000000002e-07\n",
  7500. "train: loss: 0.000143, bce: 0.000328, dice: 1.000635\n",
  7501. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7502. "saving best model\n",
  7503. "0m 9s\n",
  7504. "\n",
  7505. "\n",
  7506. "Epoch 713/799\n",
  7507. "----------\n",
  7508. "LR 1.0000000000000002e-07\n",
  7509. "train: loss: 0.000143, bce: 0.000328, dice: 1.000635\n",
  7510. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7511. "saving best model\n",
  7512. "0m 9s\n",
  7513. "\n",
  7514. "\n",
  7515. "Epoch 714/799\n",
  7516. "----------\n",
  7517. "LR 1.0000000000000002e-07\n",
  7518. "train: loss: 0.000143, bce: 0.000328, dice: 1.000635\n",
  7519. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7520. "saving best model\n",
  7521. "0m 9s\n",
  7522. "\n",
  7523. "\n",
  7524. "Epoch 715/799\n",
  7525. "----------\n",
  7526. "LR 1.0000000000000002e-07\n",
  7527. "train: loss: 0.000143, bce: 0.000328, dice: 1.000635\n",
  7528. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7529. "saving best model\n",
  7530. "0m 9s\n",
  7531. "\n",
  7532. "\n",
  7533. "Epoch 716/799\n",
  7534. "----------\n",
  7535. "LR 1.0000000000000002e-07\n",
  7536. "train: loss: 0.000143, bce: 0.000328, dice: 1.000635\n",
  7537. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7538. "saving best model\n",
  7539. "0m 9s\n",
  7540. "\n",
  7541. "\n",
  7542. "Epoch 717/799\n",
  7543. "----------\n",
  7544. "LR 1.0000000000000002e-07\n",
  7545. "train: loss: 0.000143, bce: 0.000328, dice: 1.000635\n",
  7546. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7547. "saving best model\n",
  7548. "0m 9s\n",
  7549. "\n",
  7550. "\n",
  7551. "Epoch 718/799\n",
  7552. "----------\n",
  7553. "LR 1.0000000000000002e-07\n",
  7554. "train: loss: 0.000143, bce: 0.000328, dice: 1.000635\n",
  7555. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7556. "saving best model\n",
  7557. "0m 9s\n",
  7558. "\n",
  7559. "\n",
  7560. "Epoch 719/799\n",
  7561. "----------\n",
  7562. "LR 1.0000000000000002e-07\n",
  7563. "train: loss: 0.000143, bce: 0.000328, dice: 1.000635\n",
  7564. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7565. "saving best model\n",
  7566. "0m 9s\n",
  7567. "\n",
  7568. "\n",
  7569. "Epoch 720/799\n",
  7570. "----------\n",
  7571. "LR 1.0000000000000002e-07\n",
  7572. "train: loss: 0.000143, bce: 0.000328, dice: 1.000635\n",
  7573. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7574. "saving best model\n",
  7575. "0m 9s\n",
  7576. "\n",
  7577. "\n",
  7578. "Epoch 721/799\n",
  7579. "----------\n",
  7580. "LR 1.0000000000000002e-07\n",
  7581. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7582. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7583. "saving best model\n",
  7584. "0m 9s\n",
  7585. "\n",
  7586. "\n",
  7587. "Epoch 722/799\n",
  7588. "----------\n",
  7589. "LR 1.0000000000000002e-07\n",
  7590. "train: loss: 0.000143, bce: 0.000328, dice: 1.000635\n",
  7591. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7592. "saving best model\n",
  7593. "0m 9s\n",
  7594. "\n",
  7595. "\n",
  7596. "Epoch 723/799\n",
  7597. "----------\n",
  7598. "LR 1.0000000000000002e-07\n",
  7599. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7600. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7601. "saving best model\n",
  7602. "0m 9s\n",
  7603. "\n",
  7604. "\n",
  7605. "Epoch 724/799\n",
  7606. "----------\n",
  7607. "LR 1.0000000000000002e-07\n",
  7608. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7609. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7610. "saving best model\n",
  7611. "0m 9s\n",
  7612. "\n",
  7613. "\n",
  7614. "Epoch 725/799\n",
  7615. "----------\n",
  7616. "LR 1.0000000000000002e-07\n",
  7617. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7618. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7619. "saving best model\n",
  7620. "0m 9s\n",
  7621. "\n",
  7622. "\n",
  7623. "Epoch 726/799\n",
  7624. "----------\n",
  7625. "LR 1.0000000000000002e-07\n",
  7626. "train: loss: 0.000143, bce: 0.000328, dice: 1.000635\n",
  7627. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7628. "saving best model\n",
  7629. "0m 9s\n",
  7630. "\n",
  7631. "\n",
  7632. "Epoch 727/799\n",
  7633. "----------\n",
  7634. "LR 1.0000000000000002e-07\n",
  7635. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7636. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7637. "saving best model\n",
  7638. "0m 9s\n",
  7639. "\n",
  7640. "\n",
  7641. "Epoch 728/799\n",
  7642. "----------\n",
  7643. "LR 1.0000000000000002e-07\n",
  7644. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7645. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7646. "saving best model\n",
  7647. "0m 9s\n",
  7648. "\n",
  7649. "\n",
  7650. "Epoch 729/799\n",
  7651. "----------\n",
  7652. "LR 1.0000000000000002e-07\n",
  7653. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7654. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7655. "saving best model\n",
  7656. "0m 9s\n",
  7657. "\n",
  7658. "\n",
  7659. "Epoch 730/799\n",
  7660. "----------\n",
  7661. "LR 1.0000000000000002e-07\n",
  7662. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7663. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7664. "saving best model\n",
  7665. "0m 9s\n",
  7666. "\n",
  7667. "\n",
  7668. "Epoch 731/799\n",
  7669. "----------\n",
  7670. "LR 1.0000000000000002e-07\n",
  7671. "train: loss: 0.000143, bce: 0.000328, dice: 1.000635\n",
  7672. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7673. "saving best model\n",
  7674. "0m 9s\n",
  7675. "\n",
  7676. "\n",
  7677. "Epoch 732/799\n",
  7678. "----------\n",
  7679. "LR 1.0000000000000002e-07\n",
  7680. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7681. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7682. "saving best model\n",
  7683. "0m 9s\n",
  7684. "\n",
  7685. "\n",
  7686. "Epoch 733/799\n",
  7687. "----------\n",
  7688. "LR 1.0000000000000002e-07\n",
  7689. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7690. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7691. "saving best model\n",
  7692. "0m 9s\n",
  7693. "\n",
  7694. "\n",
  7695. "Epoch 734/799\n",
  7696. "----------\n",
  7697. "LR 1.0000000000000002e-07\n",
  7698. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7699. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7700. "saving best model\n",
  7701. "0m 9s\n",
  7702. "\n",
  7703. "\n",
  7704. "Epoch 735/799\n",
  7705. "----------\n",
  7706. "LR 1.0000000000000002e-07\n",
  7707. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7708. "val: loss: 0.000147, bce: 0.000357, dice: 1.001176\n",
  7709. "saving best model\n",
  7710. "0m 9s\n",
  7711. "\n",
  7712. "\n",
  7713. "Epoch 736/799\n",
  7714. "----------\n",
  7715. "LR 1.0000000000000002e-07\n",
  7716. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7717. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7718. "saving best model\n",
  7719. "0m 9s\n",
  7720. "\n",
  7721. "\n",
  7722. "Epoch 737/799\n",
  7723. "----------\n",
  7724. "LR 1.0000000000000002e-07\n",
  7725. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7726. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7727. "saving best model\n",
  7728. "0m 9s\n",
  7729. "\n",
  7730. "\n",
  7731. "Epoch 738/799\n",
  7732. "----------\n",
  7733. "LR 1.0000000000000002e-07\n",
  7734. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7735. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7736. "saving best model\n",
  7737. "0m 9s\n",
  7738. "\n",
  7739. "\n",
  7740. "Epoch 739/799\n",
  7741. "----------\n",
  7742. "LR 1.0000000000000002e-07\n",
  7743. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7744. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7745. "saving best model\n",
  7746. "0m 9s\n",
  7747. "\n",
  7748. "\n",
  7749. "Epoch 740/799\n",
  7750. "----------\n",
  7751. "LR 1.0000000000000002e-07\n",
  7752. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7753. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7754. "saving best model\n",
  7755. "0m 9s\n",
  7756. "\n",
  7757. "\n",
  7758. "Epoch 741/799\n",
  7759. "----------\n",
  7760. "LR 1.0000000000000002e-07\n",
  7761. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7762. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7763. "saving best model\n",
  7764. "0m 9s\n",
  7765. "\n",
  7766. "\n",
  7767. "Epoch 742/799\n",
  7768. "----------\n",
  7769. "LR 1.0000000000000002e-07\n",
  7770. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7771. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7772. "saving best model\n",
  7773. "0m 9s\n",
  7774. "\n",
  7775. "\n",
  7776. "Epoch 743/799\n",
  7777. "----------\n",
  7778. "LR 1.0000000000000002e-07\n",
  7779. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7780. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7781. "saving best model\n",
  7782. "0m 9s\n",
  7783. "\n",
  7784. "\n",
  7785. "Epoch 744/799\n",
  7786. "----------\n",
  7787. "LR 1.0000000000000002e-07\n",
  7788. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7789. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7790. "saving best model\n",
  7791. "0m 9s\n",
  7792. "\n",
  7793. "\n",
  7794. "Epoch 745/799\n",
  7795. "----------\n",
  7796. "LR 1.0000000000000002e-07\n",
  7797. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7798. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7799. "saving best model\n",
  7800. "0m 9s\n",
  7801. "\n",
  7802. "\n",
  7803. "Epoch 746/799\n",
  7804. "----------\n",
  7805. "LR 1.0000000000000002e-07\n",
  7806. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7807. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7808. "saving best model\n",
  7809. "0m 9s\n",
  7810. "\n",
  7811. "\n",
  7812. "Epoch 747/799\n",
  7813. "----------\n",
  7814. "LR 1.0000000000000002e-07\n",
  7815. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7816. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7817. "saving best model\n",
  7818. "0m 9s\n",
  7819. "\n",
  7820. "\n",
  7821. "Epoch 748/799\n",
  7822. "----------\n",
  7823. "LR 1.0000000000000002e-07\n",
  7824. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7825. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7826. "saving best model\n",
  7827. "0m 9s\n",
  7828. "\n",
  7829. "\n",
  7830. "Epoch 749/799\n",
  7831. "----------\n",
  7832. "LR 1.0000000000000002e-07\n",
  7833. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7834. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7835. "saving best model\n",
  7836. "0m 9s\n",
  7837. "\n",
  7838. "\n",
  7839. "Epoch 750/799\n",
  7840. "----------\n",
  7841. "LR 1.0000000000000002e-07\n",
  7842. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7843. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7844. "saving best model\n",
  7845. "0m 9s\n",
  7846. "\n",
  7847. "\n",
  7848. "Epoch 751/799\n",
  7849. "----------\n",
  7850. "LR 1.0000000000000002e-07\n",
  7851. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7852. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7853. "saving best model\n",
  7854. "0m 9s\n",
  7855. "\n",
  7856. "\n",
  7857. "Epoch 752/799\n",
  7858. "----------\n",
  7859. "LR 1.0000000000000002e-07\n",
  7860. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7861. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7862. "saving best model\n",
  7863. "0m 9s\n",
  7864. "\n",
  7865. "\n",
  7866. "Epoch 753/799\n",
  7867. "----------\n",
  7868. "LR 1.0000000000000002e-07\n",
  7869. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7870. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7871. "saving best model\n",
  7872. "0m 9s\n",
  7873. "\n",
  7874. "\n",
  7875. "Epoch 754/799\n",
  7876. "----------\n",
  7877. "LR 1.0000000000000002e-07\n",
  7878. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7879. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7880. "saving best model\n",
  7881. "0m 9s\n",
  7882. "\n",
  7883. "\n",
  7884. "Epoch 755/799\n",
  7885. "----------\n",
  7886. "LR 1.0000000000000002e-07\n",
  7887. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7888. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7889. "saving best model\n",
  7890. "0m 9s\n",
  7891. "\n",
  7892. "\n",
  7893. "Epoch 756/799\n",
  7894. "----------\n",
  7895. "LR 1.0000000000000002e-07\n",
  7896. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7897. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7898. "saving best model\n",
  7899. "0m 9s\n",
  7900. "\n",
  7901. "\n",
  7902. "Epoch 757/799\n",
  7903. "----------\n",
  7904. "LR 1.0000000000000002e-07\n",
  7905. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7906. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7907. "saving best model\n",
  7908. "0m 9s\n",
  7909. "\n",
  7910. "\n",
  7911. "Epoch 758/799\n",
  7912. "----------\n",
  7913. "LR 1.0000000000000002e-07\n",
  7914. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7915. "val: loss: 0.000147, bce: 0.000357, dice: 1.001175\n",
  7916. "saving best model\n",
  7917. "0m 9s\n",
  7918. "\n",
  7919. "\n",
  7920. "Epoch 759/799\n",
  7921. "----------\n",
  7922. "LR 1.0000000000000002e-07\n",
  7923. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7924. "val: loss: 0.000147, bce: 0.000357, dice: 1.001174\n",
  7925. "saving best model\n",
  7926. "0m 9s\n",
  7927. "\n",
  7928. "\n",
  7929. "Epoch 760/799\n",
  7930. "----------\n",
  7931. "LR 1.0000000000000002e-07\n",
  7932. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7933. "val: loss: 0.000147, bce: 0.000357, dice: 1.001174\n",
  7934. "saving best model\n",
  7935. "0m 9s\n",
  7936. "\n",
  7937. "\n",
  7938. "Epoch 761/799\n",
  7939. "----------\n",
  7940. "LR 1.0000000000000002e-07\n",
  7941. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7942. "val: loss: 0.000147, bce: 0.000357, dice: 1.001174\n",
  7943. "saving best model\n",
  7944. "0m 9s\n",
  7945. "\n",
  7946. "\n",
  7947. "Epoch 762/799\n",
  7948. "----------\n",
  7949. "LR 1.0000000000000002e-07\n",
  7950. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7951. "val: loss: 0.000147, bce: 0.000357, dice: 1.001174\n",
  7952. "saving best model\n",
  7953. "0m 9s\n",
  7954. "\n",
  7955. "\n",
  7956. "Epoch 763/799\n",
  7957. "----------\n",
  7958. "LR 1.0000000000000002e-07\n",
  7959. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7960. "val: loss: 0.000147, bce: 0.000357, dice: 1.001174\n",
  7961. "saving best model\n",
  7962. "0m 9s\n",
  7963. "\n",
  7964. "\n",
  7965. "Epoch 764/799\n",
  7966. "----------\n",
  7967. "LR 1.0000000000000002e-07\n",
  7968. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7969. "val: loss: 0.000147, bce: 0.000357, dice: 1.001174\n",
  7970. "saving best model\n",
  7971. "0m 9s\n",
  7972. "\n",
  7973. "\n",
  7974. "Epoch 765/799\n",
  7975. "----------\n",
  7976. "LR 1.0000000000000002e-07\n",
  7977. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7978. "val: loss: 0.000147, bce: 0.000357, dice: 1.001174\n",
  7979. "saving best model\n",
  7980. "0m 9s\n",
  7981. "\n",
  7982. "\n",
  7983. "Epoch 766/799\n",
  7984. "----------\n",
  7985. "LR 1.0000000000000002e-07\n",
  7986. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7987. "val: loss: 0.000147, bce: 0.000357, dice: 1.001174\n",
  7988. "saving best model\n",
  7989. "0m 9s\n",
  7990. "\n",
  7991. "\n",
  7992. "Epoch 767/799\n",
  7993. "----------\n",
  7994. "LR 1.0000000000000002e-07\n",
  7995. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  7996. "val: loss: 0.000147, bce: 0.000357, dice: 1.001174\n",
  7997. "saving best model\n",
  7998. "0m 9s\n",
  7999. "\n",
  8000. "\n",
  8001. "Epoch 768/799\n",
  8002. "----------\n",
  8003. "LR 1.0000000000000002e-07\n",
  8004. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8005. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8006. "saving best model\n",
  8007. "0m 9s\n",
  8008. "\n",
  8009. "\n",
  8010. "Epoch 769/799\n",
  8011. "----------\n",
  8012. "LR 1.0000000000000002e-07\n",
  8013. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8014. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8015. "saving best model\n",
  8016. "0m 9s\n",
  8017. "\n",
  8018. "\n",
  8019. "Epoch 770/799\n",
  8020. "----------\n",
  8021. "LR 1.0000000000000002e-07\n",
  8022. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8023. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8024. "saving best model\n",
  8025. "0m 9s\n",
  8026. "\n",
  8027. "\n",
  8028. "Epoch 771/799\n",
  8029. "----------\n",
  8030. "LR 1.0000000000000002e-07\n",
  8031. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8032. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8033. "saving best model\n",
  8034. "0m 9s\n",
  8035. "\n",
  8036. "\n",
  8037. "Epoch 772/799\n",
  8038. "----------\n",
  8039. "LR 1.0000000000000002e-07\n",
  8040. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8041. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8042. "saving best model\n",
  8043. "0m 9s\n",
  8044. "\n",
  8045. "\n",
  8046. "Epoch 773/799\n",
  8047. "----------\n",
  8048. "LR 1.0000000000000002e-07\n",
  8049. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8050. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8051. "saving best model\n",
  8052. "0m 9s\n",
  8053. "\n",
  8054. "\n",
  8055. "Epoch 774/799\n",
  8056. "----------\n",
  8057. "LR 1.0000000000000002e-07\n",
  8058. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8059. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8060. "saving best model\n",
  8061. "0m 9s\n",
  8062. "\n",
  8063. "\n",
  8064. "Epoch 775/799\n",
  8065. "----------\n",
  8066. "LR 1.0000000000000002e-07\n",
  8067. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8068. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8069. "saving best model\n",
  8070. "0m 9s\n",
  8071. "\n",
  8072. "\n",
  8073. "Epoch 776/799\n",
  8074. "----------\n",
  8075. "LR 1.0000000000000002e-07\n",
  8076. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8077. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8078. "saving best model\n",
  8079. "0m 9s\n",
  8080. "\n",
  8081. "\n",
  8082. "Epoch 777/799\n",
  8083. "----------\n",
  8084. "LR 1.0000000000000002e-07\n",
  8085. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8086. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8087. "saving best model\n",
  8088. "0m 9s\n",
  8089. "\n",
  8090. "\n",
  8091. "Epoch 778/799\n",
  8092. "----------\n",
  8093. "LR 1.0000000000000002e-07\n",
  8094. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8095. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8096. "saving best model\n",
  8097. "0m 9s\n",
  8098. "\n",
  8099. "\n",
  8100. "Epoch 779/799\n",
  8101. "----------\n",
  8102. "LR 1.0000000000000002e-07\n",
  8103. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8104. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8105. "saving best model\n",
  8106. "0m 9s\n",
  8107. "\n",
  8108. "\n",
  8109. "Epoch 780/799\n",
  8110. "----------\n",
  8111. "LR 1.0000000000000002e-07\n",
  8112. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8113. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8114. "saving best model\n",
  8115. "0m 9s\n",
  8116. "\n",
  8117. "\n",
  8118. "Epoch 781/799\n",
  8119. "----------\n",
  8120. "LR 1.0000000000000002e-07\n",
  8121. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8122. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8123. "saving best model\n",
  8124. "0m 9s\n",
  8125. "\n",
  8126. "\n",
  8127. "Epoch 782/799\n",
  8128. "----------\n",
  8129. "LR 1.0000000000000002e-07\n",
  8130. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8131. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8132. "saving best model\n",
  8133. "0m 9s\n",
  8134. "\n",
  8135. "\n",
  8136. "Epoch 783/799\n",
  8137. "----------\n",
  8138. "LR 1.0000000000000002e-07\n",
  8139. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8140. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8141. "saving best model\n",
  8142. "0m 9s\n",
  8143. "\n",
  8144. "\n",
  8145. "Epoch 784/799\n",
  8146. "----------\n",
  8147. "LR 1.0000000000000002e-07\n",
  8148. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8149. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8150. "saving best model\n",
  8151. "0m 9s\n",
  8152. "\n",
  8153. "\n",
  8154. "Epoch 785/799\n",
  8155. "----------\n",
  8156. "LR 1.0000000000000002e-07\n",
  8157. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8158. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8159. "saving best model\n",
  8160. "0m 9s\n",
  8161. "\n",
  8162. "\n",
  8163. "Epoch 786/799\n",
  8164. "----------\n",
  8165. "LR 1.0000000000000002e-07\n",
  8166. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8167. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8168. "saving best model\n",
  8169. "0m 9s\n",
  8170. "\n",
  8171. "\n",
  8172. "Epoch 787/799\n",
  8173. "----------\n",
  8174. "LR 1.0000000000000002e-07\n",
  8175. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8176. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8177. "saving best model\n",
  8178. "0m 9s\n",
  8179. "\n",
  8180. "\n",
  8181. "Epoch 788/799\n",
  8182. "----------\n",
  8183. "LR 1.0000000000000002e-07\n",
  8184. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8185. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8186. "saving best model\n",
  8187. "0m 9s\n",
  8188. "\n",
  8189. "\n",
  8190. "Epoch 789/799\n",
  8191. "----------\n",
  8192. "LR 1.0000000000000002e-07\n",
  8193. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8194. "val: loss: 0.000147, bce: 0.000356, dice: 1.001174\n",
  8195. "saving best model\n",
  8196. "0m 9s\n",
  8197. "\n",
  8198. "\n",
  8199. "Epoch 790/799\n",
  8200. "----------\n",
  8201. "LR 1.0000000000000002e-07\n",
  8202. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8203. "val: loss: 0.000146, bce: 0.000356, dice: 1.001174\n",
  8204. "saving best model\n",
  8205. "0m 9s\n",
  8206. "\n",
  8207. "\n",
  8208. "Epoch 791/799\n",
  8209. "----------\n",
  8210. "LR 1.0000000000000002e-07\n",
  8211. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8212. "val: loss: 0.000146, bce: 0.000356, dice: 1.001173\n",
  8213. "saving best model\n",
  8214. "0m 9s\n",
  8215. "\n",
  8216. "\n",
  8217. "Epoch 792/799\n",
  8218. "----------\n",
  8219. "LR 1.0000000000000002e-07\n",
  8220. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8221. "val: loss: 0.000146, bce: 0.000356, dice: 1.001173\n",
  8222. "saving best model\n",
  8223. "0m 9s\n",
  8224. "\n",
  8225. "\n",
  8226. "Epoch 793/799\n",
  8227. "----------\n",
  8228. "LR 1.0000000000000002e-07\n",
  8229. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8230. "val: loss: 0.000146, bce: 0.000356, dice: 1.001173\n",
  8231. "saving best model\n",
  8232. "0m 9s\n",
  8233. "\n",
  8234. "\n",
  8235. "Epoch 794/799\n",
  8236. "----------\n",
  8237. "LR 1.0000000000000002e-07\n",
  8238. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8239. "val: loss: 0.000146, bce: 0.000356, dice: 1.001173\n",
  8240. "saving best model\n",
  8241. "0m 9s\n",
  8242. "\n",
  8243. "\n",
  8244. "Epoch 795/799\n",
  8245. "----------\n",
  8246. "LR 1.0000000000000002e-07\n",
  8247. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8248. "val: loss: 0.000146, bce: 0.000356, dice: 1.001173\n",
  8249. "saving best model\n",
  8250. "0m 9s\n",
  8251. "\n",
  8252. "\n",
  8253. "Epoch 796/799\n",
  8254. "----------\n",
  8255. "LR 1.0000000000000002e-07\n",
  8256. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8257. "val: loss: 0.000146, bce: 0.000356, dice: 1.001173\n",
  8258. "saving best model\n",
  8259. "0m 9s\n",
  8260. "\n",
  8261. "\n",
  8262. "Epoch 797/799\n",
  8263. "----------\n",
  8264. "LR 1.0000000000000002e-07\n",
  8265. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8266. "val: loss: 0.000146, bce: 0.000356, dice: 1.001173\n",
  8267. "saving best model\n",
  8268. "0m 9s\n",
  8269. "\n",
  8270. "\n",
  8271. "Epoch 798/799\n",
  8272. "----------\n",
  8273. "LR 1.0000000000000002e-07\n",
  8274. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8275. "val: loss: 0.000146, bce: 0.000356, dice: 1.001173\n",
  8276. "saving best model\n",
  8277. "0m 9s\n",
  8278. "\n",
  8279. "\n",
  8280. "Epoch 799/799\n",
  8281. "----------\n",
  8282. "LR 1.0000000000000004e-08\n",
  8283. "train: loss: 0.000143, bce: 0.000328, dice: 1.000634\n",
  8284. "val: loss: 0.000146, bce: 0.000356, dice: 1.001173\n",
  8285. "saving best model\n",
  8286. "0m 9s\n",
  8287. "Best val loss: 0.000146\n"
  8288. ]
  8289. }
  8290. ],
  8291. "source": [
  8292. "import torch\n",
  8293. "import torch.optim as optim\n",
  8294. "from torch.optim import lr_scheduler\n",
  8295. "import time\n",
  8296. "import copy\n",
  8297. "\n",
  8298. "device = torch.device(\"cuda:1\" if torch.cuda.is_available() else \"cpu\")\n",
  8299. "# device = torch.device(\"cpu\")\n",
  8300. "# print(torch.cuda.is_available())\n",
  8301. "print(device)\n",
  8302. "# print(next(model.parameters()).is_cuda)\n",
  8303. "\n",
  8304. "# num_class = 1\n",
  8305. "\n",
  8306. "model = pytorch_unet.UNet(n_out_class).to(device, dtype=torch.float)\n",
  8307. "# model = pytorch_unet.UNet(n_out_class).to(device)\n",
  8308. "\n",
  8309. "# model = torch.hub.load('mateuszbuda/brain-segmentation-pytorch', 'unet',\n",
  8310. "# in_channels=3, out_channels=1, init_features=32, pretrained=True).to(device, dtype=torch.float32)\n",
  8311. "# model = torch.hub.load('mateuszbuda/brain-segmentation-pytorch', 'unet',\n",
  8312. "# in_channels=3, out_channels=1, init_features=32, pretrained=True).to(device, dtype=torch.float64)\n",
  8313. "\n",
  8314. "# model = NewUnet(1, 1, bilinear=False)\n",
  8315. "# model = NewUnet(dimensions=1)\n",
  8316. "\n",
  8317. "\n",
  8318. "# r1 = model(inputs)\n",
  8319. "# if torch.cuda.device_count() > 1:\n",
  8320. "# print(\"Let's use\", torch.cuda.device_count(), \"GPUs!\")\n",
  8321. "# # dim = 0 [30, xxx] -> [10, ...], [10, ...], [10, ...] on 3 GPUs\n",
  8322. "# model = nn.DataParallel(model)\n",
  8323. "\n",
  8324. "model.to(device)\n",
  8325. "# model = model.to(device, dtype=torch.float32)\n",
  8326. "\n",
  8327. "print(next(model.parameters()).is_cuda)\n",
  8328. "\n",
  8329. "# Observe that all parameters are being optimized\n",
  8330. "# optimizer_ft = optim.SGD(model.parameters(), lr=10)\n",
  8331. "optimizer_ft = optim.RMSprop(model.parameters(), lr=1e-4)\n",
  8332. "\n",
  8333. "\n",
  8334. "exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=200, gamma=0.1)\n",
  8335. "\n",
  8336. "model = train_model(model, optimizer_ft, exp_lr_scheduler, num_epochs=800, load_model=True)"
  8337. ]
  8338. },
  8339. {
  8340. "cell_type": "code",
  8341. "execution_count": null,
  8342. "metadata": {},
  8343. "outputs": [],
  8344. "source": []
  8345. },
  8346. {
  8347. "cell_type": "code",
  8348. "execution_count": 19,
  8349. "metadata": {},
  8350. "outputs": [],
  8351. "source": [
  8352. "def printImages(entering):\n",
  8353. " for im in entering:\n",
  8354. " print(np.amin(im), np.amax(im))\n",
  8355. " print(im.sum())\n",
  8356. " print(unravel_index(im.argmax(), im.shape))\n",
  8357. "# unique, counts = np.unique(img, return_counts=True)\n",
  8358. "# print(dict(zip(unique, counts)))\n",
  8359. " print()\n",
  8360. " plt.figure()\n",
  8361. " plt.imshow(im)"
  8362. ]
  8363. },
  8364. {
  8365. "cell_type": "code",
  8366. "execution_count": 26,
  8367. "metadata": {},
  8368. "outputs": [
  8369. {
  8370. "name": "stdout",
  8371. "output_type": "stream",
  8372. "text": [
  8373. "-0.22008087 4.898781\n",
  8374. "19362.621\n",
  8375. "(240, 211)\n",
  8376. "\n"
  8377. ]
  8378. },
  8379. {
  8380. "data": {
  8381. "application/javascript": [
  8382. "/* Put everything inside the global mpl namespace */\n",
  8383. "window.mpl = {};\n",
  8384. "\n",
  8385. "\n",
  8386. "mpl.get_websocket_type = function() {\n",
  8387. " if (typeof(WebSocket) !== 'undefined') {\n",
  8388. " return WebSocket;\n",
  8389. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  8390. " return MozWebSocket;\n",
  8391. " } else {\n",
  8392. " alert('Your browser does not have WebSocket support.' +\n",
  8393. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  8394. " 'Firefox 4 and 5 are also supported but you ' +\n",
  8395. " 'have to enable WebSockets in about:config.');\n",
  8396. " };\n",
  8397. "}\n",
  8398. "\n",
  8399. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  8400. " this.id = figure_id;\n",
  8401. "\n",
  8402. " this.ws = websocket;\n",
  8403. "\n",
  8404. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  8405. "\n",
  8406. " if (!this.supports_binary) {\n",
  8407. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  8408. " if (warnings) {\n",
  8409. " warnings.style.display = 'block';\n",
  8410. " warnings.textContent = (\n",
  8411. " \"This browser does not support binary websocket messages. \" +\n",
  8412. " \"Performance may be slow.\");\n",
  8413. " }\n",
  8414. " }\n",
  8415. "\n",
  8416. " this.imageObj = new Image();\n",
  8417. "\n",
  8418. " this.context = undefined;\n",
  8419. " this.message = undefined;\n",
  8420. " this.canvas = undefined;\n",
  8421. " this.rubberband_canvas = undefined;\n",
  8422. " this.rubberband_context = undefined;\n",
  8423. " this.format_dropdown = undefined;\n",
  8424. "\n",
  8425. " this.image_mode = 'full';\n",
  8426. "\n",
  8427. " this.root = $('<div/>');\n",
  8428. " this._root_extra_style(this.root)\n",
  8429. " this.root.attr('style', 'display: inline-block');\n",
  8430. "\n",
  8431. " $(parent_element).append(this.root);\n",
  8432. "\n",
  8433. " this._init_header(this);\n",
  8434. " this._init_canvas(this);\n",
  8435. " this._init_toolbar(this);\n",
  8436. "\n",
  8437. " var fig = this;\n",
  8438. "\n",
  8439. " this.waiting = false;\n",
  8440. "\n",
  8441. " this.ws.onopen = function () {\n",
  8442. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  8443. " fig.send_message(\"send_image_mode\", {});\n",
  8444. " if (mpl.ratio != 1) {\n",
  8445. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  8446. " }\n",
  8447. " fig.send_message(\"refresh\", {});\n",
  8448. " }\n",
  8449. "\n",
  8450. " this.imageObj.onload = function() {\n",
  8451. " if (fig.image_mode == 'full') {\n",
  8452. " // Full images could contain transparency (where diff images\n",
  8453. " // almost always do), so we need to clear the canvas so that\n",
  8454. " // there is no ghosting.\n",
  8455. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  8456. " }\n",
  8457. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  8458. " };\n",
  8459. "\n",
  8460. " this.imageObj.onunload = function() {\n",
  8461. " fig.ws.close();\n",
  8462. " }\n",
  8463. "\n",
  8464. " this.ws.onmessage = this._make_on_message_function(this);\n",
  8465. "\n",
  8466. " this.ondownload = ondownload;\n",
  8467. "}\n",
  8468. "\n",
  8469. "mpl.figure.prototype._init_header = function() {\n",
  8470. " var titlebar = $(\n",
  8471. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  8472. " 'ui-helper-clearfix\"/>');\n",
  8473. " var titletext = $(\n",
  8474. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  8475. " 'text-align: center; padding: 3px;\"/>');\n",
  8476. " titlebar.append(titletext)\n",
  8477. " this.root.append(titlebar);\n",
  8478. " this.header = titletext[0];\n",
  8479. "}\n",
  8480. "\n",
  8481. "\n",
  8482. "\n",
  8483. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  8484. "\n",
  8485. "}\n",
  8486. "\n",
  8487. "\n",
  8488. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  8489. "\n",
  8490. "}\n",
  8491. "\n",
  8492. "mpl.figure.prototype._init_canvas = function() {\n",
  8493. " var fig = this;\n",
  8494. "\n",
  8495. " var canvas_div = $('<div/>');\n",
  8496. "\n",
  8497. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  8498. "\n",
  8499. " function canvas_keyboard_event(event) {\n",
  8500. " return fig.key_event(event, event['data']);\n",
  8501. " }\n",
  8502. "\n",
  8503. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  8504. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  8505. " this.canvas_div = canvas_div\n",
  8506. " this._canvas_extra_style(canvas_div)\n",
  8507. " this.root.append(canvas_div);\n",
  8508. "\n",
  8509. " var canvas = $('<canvas/>');\n",
  8510. " canvas.addClass('mpl-canvas');\n",
  8511. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  8512. "\n",
  8513. " this.canvas = canvas[0];\n",
  8514. " this.context = canvas[0].getContext(\"2d\");\n",
  8515. "\n",
  8516. " var backingStore = this.context.backingStorePixelRatio ||\n",
  8517. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  8518. "\tthis.context.mozBackingStorePixelRatio ||\n",
  8519. "\tthis.context.msBackingStorePixelRatio ||\n",
  8520. "\tthis.context.oBackingStorePixelRatio ||\n",
  8521. "\tthis.context.backingStorePixelRatio || 1;\n",
  8522. "\n",
  8523. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  8524. "\n",
  8525. " var rubberband = $('<canvas/>');\n",
  8526. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  8527. "\n",
  8528. " var pass_mouse_events = true;\n",
  8529. "\n",
  8530. " canvas_div.resizable({\n",
  8531. " start: function(event, ui) {\n",
  8532. " pass_mouse_events = false;\n",
  8533. " },\n",
  8534. " resize: function(event, ui) {\n",
  8535. " fig.request_resize(ui.size.width, ui.size.height);\n",
  8536. " },\n",
  8537. " stop: function(event, ui) {\n",
  8538. " pass_mouse_events = true;\n",
  8539. " fig.request_resize(ui.size.width, ui.size.height);\n",
  8540. " },\n",
  8541. " });\n",
  8542. "\n",
  8543. " function mouse_event_fn(event) {\n",
  8544. " if (pass_mouse_events)\n",
  8545. " return fig.mouse_event(event, event['data']);\n",
  8546. " }\n",
  8547. "\n",
  8548. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  8549. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  8550. " // Throttle sequential mouse events to 1 every 20ms.\n",
  8551. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  8552. "\n",
  8553. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  8554. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  8555. "\n",
  8556. " canvas_div.on(\"wheel\", function (event) {\n",
  8557. " event = event.originalEvent;\n",
  8558. " event['data'] = 'scroll'\n",
  8559. " if (event.deltaY < 0) {\n",
  8560. " event.step = 1;\n",
  8561. " } else {\n",
  8562. " event.step = -1;\n",
  8563. " }\n",
  8564. " mouse_event_fn(event);\n",
  8565. " });\n",
  8566. "\n",
  8567. " canvas_div.append(canvas);\n",
  8568. " canvas_div.append(rubberband);\n",
  8569. "\n",
  8570. " this.rubberband = rubberband;\n",
  8571. " this.rubberband_canvas = rubberband[0];\n",
  8572. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  8573. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  8574. "\n",
  8575. " this._resize_canvas = function(width, height) {\n",
  8576. " // Keep the size of the canvas, canvas container, and rubber band\n",
  8577. " // canvas in synch.\n",
  8578. " canvas_div.css('width', width)\n",
  8579. " canvas_div.css('height', height)\n",
  8580. "\n",
  8581. " canvas.attr('width', width * mpl.ratio);\n",
  8582. " canvas.attr('height', height * mpl.ratio);\n",
  8583. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  8584. "\n",
  8585. " rubberband.attr('width', width);\n",
  8586. " rubberband.attr('height', height);\n",
  8587. " }\n",
  8588. "\n",
  8589. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  8590. " // upon first draw.\n",
  8591. " this._resize_canvas(600, 600);\n",
  8592. "\n",
  8593. " // Disable right mouse context menu.\n",
  8594. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  8595. " return false;\n",
  8596. " });\n",
  8597. "\n",
  8598. " function set_focus () {\n",
  8599. " canvas.focus();\n",
  8600. " canvas_div.focus();\n",
  8601. " }\n",
  8602. "\n",
  8603. " window.setTimeout(set_focus, 100);\n",
  8604. "}\n",
  8605. "\n",
  8606. "mpl.figure.prototype._init_toolbar = function() {\n",
  8607. " var fig = this;\n",
  8608. "\n",
  8609. " var nav_element = $('<div/>')\n",
  8610. " nav_element.attr('style', 'width: 100%');\n",
  8611. " this.root.append(nav_element);\n",
  8612. "\n",
  8613. " // Define a callback function for later on.\n",
  8614. " function toolbar_event(event) {\n",
  8615. " return fig.toolbar_button_onclick(event['data']);\n",
  8616. " }\n",
  8617. " function toolbar_mouse_event(event) {\n",
  8618. " return fig.toolbar_button_onmouseover(event['data']);\n",
  8619. " }\n",
  8620. "\n",
  8621. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  8622. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  8623. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  8624. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  8625. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  8626. "\n",
  8627. " if (!name) {\n",
  8628. " // put a spacer in here.\n",
  8629. " continue;\n",
  8630. " }\n",
  8631. " var button = $('<button/>');\n",
  8632. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  8633. " 'ui-button-icon-only');\n",
  8634. " button.attr('role', 'button');\n",
  8635. " button.attr('aria-disabled', 'false');\n",
  8636. " button.click(method_name, toolbar_event);\n",
  8637. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  8638. "\n",
  8639. " var icon_img = $('<span/>');\n",
  8640. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  8641. " icon_img.addClass(image);\n",
  8642. " icon_img.addClass('ui-corner-all');\n",
  8643. "\n",
  8644. " var tooltip_span = $('<span/>');\n",
  8645. " tooltip_span.addClass('ui-button-text');\n",
  8646. " tooltip_span.html(tooltip);\n",
  8647. "\n",
  8648. " button.append(icon_img);\n",
  8649. " button.append(tooltip_span);\n",
  8650. "\n",
  8651. " nav_element.append(button);\n",
  8652. " }\n",
  8653. "\n",
  8654. " var fmt_picker_span = $('<span/>');\n",
  8655. "\n",
  8656. " var fmt_picker = $('<select/>');\n",
  8657. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  8658. " fmt_picker_span.append(fmt_picker);\n",
  8659. " nav_element.append(fmt_picker_span);\n",
  8660. " this.format_dropdown = fmt_picker[0];\n",
  8661. "\n",
  8662. " for (var ind in mpl.extensions) {\n",
  8663. " var fmt = mpl.extensions[ind];\n",
  8664. " var option = $(\n",
  8665. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  8666. " fmt_picker.append(option)\n",
  8667. " }\n",
  8668. "\n",
  8669. " // Add hover states to the ui-buttons\n",
  8670. " $( \".ui-button\" ).hover(\n",
  8671. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  8672. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  8673. " );\n",
  8674. "\n",
  8675. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  8676. " nav_element.append(status_bar);\n",
  8677. " this.message = status_bar[0];\n",
  8678. "}\n",
  8679. "\n",
  8680. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  8681. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  8682. " // which will in turn request a refresh of the image.\n",
  8683. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  8684. "}\n",
  8685. "\n",
  8686. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  8687. " properties['type'] = type;\n",
  8688. " properties['figure_id'] = this.id;\n",
  8689. " this.ws.send(JSON.stringify(properties));\n",
  8690. "}\n",
  8691. "\n",
  8692. "mpl.figure.prototype.send_draw_message = function() {\n",
  8693. " if (!this.waiting) {\n",
  8694. " this.waiting = true;\n",
  8695. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  8696. " }\n",
  8697. "}\n",
  8698. "\n",
  8699. "\n",
  8700. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  8701. " var format_dropdown = fig.format_dropdown;\n",
  8702. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  8703. " fig.ondownload(fig, format);\n",
  8704. "}\n",
  8705. "\n",
  8706. "\n",
  8707. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  8708. " var size = msg['size'];\n",
  8709. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  8710. " fig._resize_canvas(size[0], size[1]);\n",
  8711. " fig.send_message(\"refresh\", {});\n",
  8712. " };\n",
  8713. "}\n",
  8714. "\n",
  8715. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  8716. " var x0 = msg['x0'] / mpl.ratio;\n",
  8717. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  8718. " var x1 = msg['x1'] / mpl.ratio;\n",
  8719. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  8720. " x0 = Math.floor(x0) + 0.5;\n",
  8721. " y0 = Math.floor(y0) + 0.5;\n",
  8722. " x1 = Math.floor(x1) + 0.5;\n",
  8723. " y1 = Math.floor(y1) + 0.5;\n",
  8724. " var min_x = Math.min(x0, x1);\n",
  8725. " var min_y = Math.min(y0, y1);\n",
  8726. " var width = Math.abs(x1 - x0);\n",
  8727. " var height = Math.abs(y1 - y0);\n",
  8728. "\n",
  8729. " fig.rubberband_context.clearRect(\n",
  8730. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  8731. "\n",
  8732. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  8733. "}\n",
  8734. "\n",
  8735. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  8736. " // Updates the figure title.\n",
  8737. " fig.header.textContent = msg['label'];\n",
  8738. "}\n",
  8739. "\n",
  8740. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  8741. " var cursor = msg['cursor'];\n",
  8742. " switch(cursor)\n",
  8743. " {\n",
  8744. " case 0:\n",
  8745. " cursor = 'pointer';\n",
  8746. " break;\n",
  8747. " case 1:\n",
  8748. " cursor = 'default';\n",
  8749. " break;\n",
  8750. " case 2:\n",
  8751. " cursor = 'crosshair';\n",
  8752. " break;\n",
  8753. " case 3:\n",
  8754. " cursor = 'move';\n",
  8755. " break;\n",
  8756. " }\n",
  8757. " fig.rubberband_canvas.style.cursor = cursor;\n",
  8758. "}\n",
  8759. "\n",
  8760. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  8761. " fig.message.textContent = msg['message'];\n",
  8762. "}\n",
  8763. "\n",
  8764. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  8765. " // Request the server to send over a new figure.\n",
  8766. " fig.send_draw_message();\n",
  8767. "}\n",
  8768. "\n",
  8769. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  8770. " fig.image_mode = msg['mode'];\n",
  8771. "}\n",
  8772. "\n",
  8773. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  8774. " // Called whenever the canvas gets updated.\n",
  8775. " this.send_message(\"ack\", {});\n",
  8776. "}\n",
  8777. "\n",
  8778. "// A function to construct a web socket function for onmessage handling.\n",
  8779. "// Called in the figure constructor.\n",
  8780. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  8781. " return function socket_on_message(evt) {\n",
  8782. " if (evt.data instanceof Blob) {\n",
  8783. " /* FIXME: We get \"Resource interpreted as Image but\n",
  8784. " * transferred with MIME type text/plain:\" errors on\n",
  8785. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  8786. " * to be part of the websocket stream */\n",
  8787. " evt.data.type = \"image/png\";\n",
  8788. "\n",
  8789. " /* Free the memory for the previous frames */\n",
  8790. " if (fig.imageObj.src) {\n",
  8791. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  8792. " fig.imageObj.src);\n",
  8793. " }\n",
  8794. "\n",
  8795. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  8796. " evt.data);\n",
  8797. " fig.updated_canvas_event();\n",
  8798. " fig.waiting = false;\n",
  8799. " return;\n",
  8800. " }\n",
  8801. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  8802. " fig.imageObj.src = evt.data;\n",
  8803. " fig.updated_canvas_event();\n",
  8804. " fig.waiting = false;\n",
  8805. " return;\n",
  8806. " }\n",
  8807. "\n",
  8808. " var msg = JSON.parse(evt.data);\n",
  8809. " var msg_type = msg['type'];\n",
  8810. "\n",
  8811. " // Call the \"handle_{type}\" callback, which takes\n",
  8812. " // the figure and JSON message as its only arguments.\n",
  8813. " try {\n",
  8814. " var callback = fig[\"handle_\" + msg_type];\n",
  8815. " } catch (e) {\n",
  8816. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  8817. " return;\n",
  8818. " }\n",
  8819. "\n",
  8820. " if (callback) {\n",
  8821. " try {\n",
  8822. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  8823. " callback(fig, msg);\n",
  8824. " } catch (e) {\n",
  8825. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  8826. " }\n",
  8827. " }\n",
  8828. " };\n",
  8829. "}\n",
  8830. "\n",
  8831. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  8832. "mpl.findpos = function(e) {\n",
  8833. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  8834. " var targ;\n",
  8835. " if (!e)\n",
  8836. " e = window.event;\n",
  8837. " if (e.target)\n",
  8838. " targ = e.target;\n",
  8839. " else if (e.srcElement)\n",
  8840. " targ = e.srcElement;\n",
  8841. " if (targ.nodeType == 3) // defeat Safari bug\n",
  8842. " targ = targ.parentNode;\n",
  8843. "\n",
  8844. " // jQuery normalizes the pageX and pageY\n",
  8845. " // pageX,Y are the mouse positions relative to the document\n",
  8846. " // offset() returns the position of the element relative to the document\n",
  8847. " var x = e.pageX - $(targ).offset().left;\n",
  8848. " var y = e.pageY - $(targ).offset().top;\n",
  8849. "\n",
  8850. " return {\"x\": x, \"y\": y};\n",
  8851. "};\n",
  8852. "\n",
  8853. "/*\n",
  8854. " * return a copy of an object with only non-object keys\n",
  8855. " * we need this to avoid circular references\n",
  8856. " * http://stackoverflow.com/a/24161582/3208463\n",
  8857. " */\n",
  8858. "function simpleKeys (original) {\n",
  8859. " return Object.keys(original).reduce(function (obj, key) {\n",
  8860. " if (typeof original[key] !== 'object')\n",
  8861. " obj[key] = original[key]\n",
  8862. " return obj;\n",
  8863. " }, {});\n",
  8864. "}\n",
  8865. "\n",
  8866. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  8867. " var canvas_pos = mpl.findpos(event)\n",
  8868. "\n",
  8869. " if (name === 'button_press')\n",
  8870. " {\n",
  8871. " this.canvas.focus();\n",
  8872. " this.canvas_div.focus();\n",
  8873. " }\n",
  8874. "\n",
  8875. " var x = canvas_pos.x * mpl.ratio;\n",
  8876. " var y = canvas_pos.y * mpl.ratio;\n",
  8877. "\n",
  8878. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  8879. " step: event.step,\n",
  8880. " guiEvent: simpleKeys(event)});\n",
  8881. "\n",
  8882. " /* This prevents the web browser from automatically changing to\n",
  8883. " * the text insertion cursor when the button is pressed. We want\n",
  8884. " * to control all of the cursor setting manually through the\n",
  8885. " * 'cursor' event from matplotlib */\n",
  8886. " event.preventDefault();\n",
  8887. " return false;\n",
  8888. "}\n",
  8889. "\n",
  8890. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  8891. " // Handle any extra behaviour associated with a key event\n",
  8892. "}\n",
  8893. "\n",
  8894. "mpl.figure.prototype.key_event = function(event, name) {\n",
  8895. "\n",
  8896. " // Prevent repeat events\n",
  8897. " if (name == 'key_press')\n",
  8898. " {\n",
  8899. " if (event.which === this._key)\n",
  8900. " return;\n",
  8901. " else\n",
  8902. " this._key = event.which;\n",
  8903. " }\n",
  8904. " if (name == 'key_release')\n",
  8905. " this._key = null;\n",
  8906. "\n",
  8907. " var value = '';\n",
  8908. " if (event.ctrlKey && event.which != 17)\n",
  8909. " value += \"ctrl+\";\n",
  8910. " if (event.altKey && event.which != 18)\n",
  8911. " value += \"alt+\";\n",
  8912. " if (event.shiftKey && event.which != 16)\n",
  8913. " value += \"shift+\";\n",
  8914. "\n",
  8915. " value += 'k';\n",
  8916. " value += event.which.toString();\n",
  8917. "\n",
  8918. " this._key_event_extra(event, name);\n",
  8919. "\n",
  8920. " this.send_message(name, {key: value,\n",
  8921. " guiEvent: simpleKeys(event)});\n",
  8922. " return false;\n",
  8923. "}\n",
  8924. "\n",
  8925. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  8926. " if (name == 'download') {\n",
  8927. " this.handle_save(this, null);\n",
  8928. " } else {\n",
  8929. " this.send_message(\"toolbar_button\", {name: name});\n",
  8930. " }\n",
  8931. "};\n",
  8932. "\n",
  8933. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  8934. " this.message.textContent = tooltip;\n",
  8935. "};\n",
  8936. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  8937. "\n",
  8938. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  8939. "\n",
  8940. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  8941. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  8942. " // object with the appropriate methods. Currently this is a non binary\n",
  8943. " // socket, so there is still some room for performance tuning.\n",
  8944. " var ws = {};\n",
  8945. "\n",
  8946. " ws.close = function() {\n",
  8947. " comm.close()\n",
  8948. " };\n",
  8949. " ws.send = function(m) {\n",
  8950. " //console.log('sending', m);\n",
  8951. " comm.send(m);\n",
  8952. " };\n",
  8953. " // Register the callback with on_msg.\n",
  8954. " comm.on_msg(function(msg) {\n",
  8955. " //console.log('receiving', msg['content']['data'], msg);\n",
  8956. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  8957. " ws.onmessage(msg['content']['data'])\n",
  8958. " });\n",
  8959. " return ws;\n",
  8960. "}\n",
  8961. "\n",
  8962. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  8963. " // This is the function which gets called when the mpl process\n",
  8964. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  8965. "\n",
  8966. " var id = msg.content.data.id;\n",
  8967. " // Get hold of the div created by the display call when the Comm\n",
  8968. " // socket was opened in Python.\n",
  8969. " var element = $(\"#\" + id);\n",
  8970. " var ws_proxy = comm_websocket_adapter(comm)\n",
  8971. "\n",
  8972. " function ondownload(figure, format) {\n",
  8973. " window.open(figure.imageObj.src);\n",
  8974. " }\n",
  8975. "\n",
  8976. " var fig = new mpl.figure(id, ws_proxy,\n",
  8977. " ondownload,\n",
  8978. " element.get(0));\n",
  8979. "\n",
  8980. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  8981. " // web socket which is closed, not our websocket->open comm proxy.\n",
  8982. " ws_proxy.onopen();\n",
  8983. "\n",
  8984. " fig.parent_element = element.get(0);\n",
  8985. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  8986. " if (!fig.cell_info) {\n",
  8987. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  8988. " return;\n",
  8989. " }\n",
  8990. "\n",
  8991. " var output_index = fig.cell_info[2]\n",
  8992. " var cell = fig.cell_info[0];\n",
  8993. "\n",
  8994. "};\n",
  8995. "\n",
  8996. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  8997. " var width = fig.canvas.width/mpl.ratio\n",
  8998. " fig.root.unbind('remove')\n",
  8999. "\n",
  9000. " // Update the output cell to use the data from the current canvas.\n",
  9001. " fig.push_to_output();\n",
  9002. " var dataURL = fig.canvas.toDataURL();\n",
  9003. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  9004. " // the notebook keyboard shortcuts fail.\n",
  9005. " IPython.keyboard_manager.enable()\n",
  9006. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  9007. " fig.close_ws(fig, msg);\n",
  9008. "}\n",
  9009. "\n",
  9010. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  9011. " fig.send_message('closing', msg);\n",
  9012. " // fig.ws.close()\n",
  9013. "}\n",
  9014. "\n",
  9015. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  9016. " // Turn the data on the canvas into data in the output cell.\n",
  9017. " var width = this.canvas.width/mpl.ratio\n",
  9018. " var dataURL = this.canvas.toDataURL();\n",
  9019. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  9020. "}\n",
  9021. "\n",
  9022. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  9023. " // Tell IPython that the notebook contents must change.\n",
  9024. " IPython.notebook.set_dirty(true);\n",
  9025. " this.send_message(\"ack\", {});\n",
  9026. " var fig = this;\n",
  9027. " // Wait a second, then push the new image to the DOM so\n",
  9028. " // that it is saved nicely (might be nice to debounce this).\n",
  9029. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  9030. "}\n",
  9031. "\n",
  9032. "mpl.figure.prototype._init_toolbar = function() {\n",
  9033. " var fig = this;\n",
  9034. "\n",
  9035. " var nav_element = $('<div/>')\n",
  9036. " nav_element.attr('style', 'width: 100%');\n",
  9037. " this.root.append(nav_element);\n",
  9038. "\n",
  9039. " // Define a callback function for later on.\n",
  9040. " function toolbar_event(event) {\n",
  9041. " return fig.toolbar_button_onclick(event['data']);\n",
  9042. " }\n",
  9043. " function toolbar_mouse_event(event) {\n",
  9044. " return fig.toolbar_button_onmouseover(event['data']);\n",
  9045. " }\n",
  9046. "\n",
  9047. " for(var toolbar_ind in mpl.toolbar_items){\n",
  9048. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  9049. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  9050. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  9051. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  9052. "\n",
  9053. " if (!name) { continue; };\n",
  9054. "\n",
  9055. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  9056. " button.click(method_name, toolbar_event);\n",
  9057. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  9058. " nav_element.append(button);\n",
  9059. " }\n",
  9060. "\n",
  9061. " // Add the status bar.\n",
  9062. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  9063. " nav_element.append(status_bar);\n",
  9064. " this.message = status_bar[0];\n",
  9065. "\n",
  9066. " // Add the close button to the window.\n",
  9067. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  9068. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  9069. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  9070. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  9071. " buttongrp.append(button);\n",
  9072. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  9073. " titlebar.prepend(buttongrp);\n",
  9074. "}\n",
  9075. "\n",
  9076. "mpl.figure.prototype._root_extra_style = function(el){\n",
  9077. " var fig = this\n",
  9078. " el.on(\"remove\", function(){\n",
  9079. "\tfig.close_ws(fig, {});\n",
  9080. " });\n",
  9081. "}\n",
  9082. "\n",
  9083. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  9084. " // this is important to make the div 'focusable\n",
  9085. " el.attr('tabindex', 0)\n",
  9086. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  9087. " // off when our div gets focus\n",
  9088. "\n",
  9089. " // location in version 3\n",
  9090. " if (IPython.notebook.keyboard_manager) {\n",
  9091. " IPython.notebook.keyboard_manager.register_events(el);\n",
  9092. " }\n",
  9093. " else {\n",
  9094. " // location in version 2\n",
  9095. " IPython.keyboard_manager.register_events(el);\n",
  9096. " }\n",
  9097. "\n",
  9098. "}\n",
  9099. "\n",
  9100. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  9101. " var manager = IPython.notebook.keyboard_manager;\n",
  9102. " if (!manager)\n",
  9103. " manager = IPython.keyboard_manager;\n",
  9104. "\n",
  9105. " // Check for shift+enter\n",
  9106. " if (event.shiftKey && event.which == 13) {\n",
  9107. " this.canvas_div.blur();\n",
  9108. " event.shiftKey = false;\n",
  9109. " // Send a \"J\" for go to next cell\n",
  9110. " event.which = 74;\n",
  9111. " event.keyCode = 74;\n",
  9112. " manager.command_mode();\n",
  9113. " manager.handle_keydown(event);\n",
  9114. " }\n",
  9115. "}\n",
  9116. "\n",
  9117. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  9118. " fig.ondownload(fig, null);\n",
  9119. "}\n",
  9120. "\n",
  9121. "\n",
  9122. "mpl.find_output_cell = function(html_output) {\n",
  9123. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  9124. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  9125. " // IPython event is triggered only after the cells have been serialised, which for\n",
  9126. " // our purposes (turning an active figure into a static one), is too late.\n",
  9127. " var cells = IPython.notebook.get_cells();\n",
  9128. " var ncells = cells.length;\n",
  9129. " for (var i=0; i<ncells; i++) {\n",
  9130. " var cell = cells[i];\n",
  9131. " if (cell.cell_type === 'code'){\n",
  9132. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  9133. " var data = cell.output_area.outputs[j];\n",
  9134. " if (data.data) {\n",
  9135. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  9136. " data = data.data;\n",
  9137. " }\n",
  9138. " if (data['text/html'] == html_output) {\n",
  9139. " return [cell, data, j];\n",
  9140. " }\n",
  9141. " }\n",
  9142. " }\n",
  9143. " }\n",
  9144. "}\n",
  9145. "\n",
  9146. "// Register the function which deals with the matplotlib target/channel.\n",
  9147. "// The kernel may be null if the page has been refreshed.\n",
  9148. "if (IPython.notebook.kernel != null) {\n",
  9149. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  9150. "}\n"
  9151. ],
  9152. "text/plain": [
  9153. "<IPython.core.display.Javascript object>"
  9154. ]
  9155. },
  9156. "metadata": {},
  9157. "output_type": "display_data"
  9158. },
  9159. {
  9160. "data": {
  9161. "text/html": [
  9162. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  9163. ],
  9164. "text/plain": [
  9165. "<IPython.core.display.HTML object>"
  9166. ]
  9167. },
  9168. "metadata": {},
  9169. "output_type": "display_data"
  9170. },
  9171. {
  9172. "name": "stdout",
  9173. "output_type": "stream",
  9174. "text": [
  9175. "0.0 1.0\n",
  9176. "453.0\n",
  9177. "(355, 312)\n",
  9178. "\n"
  9179. ]
  9180. },
  9181. {
  9182. "data": {
  9183. "application/javascript": [
  9184. "/* Put everything inside the global mpl namespace */\n",
  9185. "window.mpl = {};\n",
  9186. "\n",
  9187. "\n",
  9188. "mpl.get_websocket_type = function() {\n",
  9189. " if (typeof(WebSocket) !== 'undefined') {\n",
  9190. " return WebSocket;\n",
  9191. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  9192. " return MozWebSocket;\n",
  9193. " } else {\n",
  9194. " alert('Your browser does not have WebSocket support.' +\n",
  9195. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  9196. " 'Firefox 4 and 5 are also supported but you ' +\n",
  9197. " 'have to enable WebSockets in about:config.');\n",
  9198. " };\n",
  9199. "}\n",
  9200. "\n",
  9201. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  9202. " this.id = figure_id;\n",
  9203. "\n",
  9204. " this.ws = websocket;\n",
  9205. "\n",
  9206. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  9207. "\n",
  9208. " if (!this.supports_binary) {\n",
  9209. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  9210. " if (warnings) {\n",
  9211. " warnings.style.display = 'block';\n",
  9212. " warnings.textContent = (\n",
  9213. " \"This browser does not support binary websocket messages. \" +\n",
  9214. " \"Performance may be slow.\");\n",
  9215. " }\n",
  9216. " }\n",
  9217. "\n",
  9218. " this.imageObj = new Image();\n",
  9219. "\n",
  9220. " this.context = undefined;\n",
  9221. " this.message = undefined;\n",
  9222. " this.canvas = undefined;\n",
  9223. " this.rubberband_canvas = undefined;\n",
  9224. " this.rubberband_context = undefined;\n",
  9225. " this.format_dropdown = undefined;\n",
  9226. "\n",
  9227. " this.image_mode = 'full';\n",
  9228. "\n",
  9229. " this.root = $('<div/>');\n",
  9230. " this._root_extra_style(this.root)\n",
  9231. " this.root.attr('style', 'display: inline-block');\n",
  9232. "\n",
  9233. " $(parent_element).append(this.root);\n",
  9234. "\n",
  9235. " this._init_header(this);\n",
  9236. " this._init_canvas(this);\n",
  9237. " this._init_toolbar(this);\n",
  9238. "\n",
  9239. " var fig = this;\n",
  9240. "\n",
  9241. " this.waiting = false;\n",
  9242. "\n",
  9243. " this.ws.onopen = function () {\n",
  9244. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  9245. " fig.send_message(\"send_image_mode\", {});\n",
  9246. " if (mpl.ratio != 1) {\n",
  9247. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  9248. " }\n",
  9249. " fig.send_message(\"refresh\", {});\n",
  9250. " }\n",
  9251. "\n",
  9252. " this.imageObj.onload = function() {\n",
  9253. " if (fig.image_mode == 'full') {\n",
  9254. " // Full images could contain transparency (where diff images\n",
  9255. " // almost always do), so we need to clear the canvas so that\n",
  9256. " // there is no ghosting.\n",
  9257. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  9258. " }\n",
  9259. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  9260. " };\n",
  9261. "\n",
  9262. " this.imageObj.onunload = function() {\n",
  9263. " fig.ws.close();\n",
  9264. " }\n",
  9265. "\n",
  9266. " this.ws.onmessage = this._make_on_message_function(this);\n",
  9267. "\n",
  9268. " this.ondownload = ondownload;\n",
  9269. "}\n",
  9270. "\n",
  9271. "mpl.figure.prototype._init_header = function() {\n",
  9272. " var titlebar = $(\n",
  9273. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  9274. " 'ui-helper-clearfix\"/>');\n",
  9275. " var titletext = $(\n",
  9276. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  9277. " 'text-align: center; padding: 3px;\"/>');\n",
  9278. " titlebar.append(titletext)\n",
  9279. " this.root.append(titlebar);\n",
  9280. " this.header = titletext[0];\n",
  9281. "}\n",
  9282. "\n",
  9283. "\n",
  9284. "\n",
  9285. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  9286. "\n",
  9287. "}\n",
  9288. "\n",
  9289. "\n",
  9290. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  9291. "\n",
  9292. "}\n",
  9293. "\n",
  9294. "mpl.figure.prototype._init_canvas = function() {\n",
  9295. " var fig = this;\n",
  9296. "\n",
  9297. " var canvas_div = $('<div/>');\n",
  9298. "\n",
  9299. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  9300. "\n",
  9301. " function canvas_keyboard_event(event) {\n",
  9302. " return fig.key_event(event, event['data']);\n",
  9303. " }\n",
  9304. "\n",
  9305. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  9306. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  9307. " this.canvas_div = canvas_div\n",
  9308. " this._canvas_extra_style(canvas_div)\n",
  9309. " this.root.append(canvas_div);\n",
  9310. "\n",
  9311. " var canvas = $('<canvas/>');\n",
  9312. " canvas.addClass('mpl-canvas');\n",
  9313. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  9314. "\n",
  9315. " this.canvas = canvas[0];\n",
  9316. " this.context = canvas[0].getContext(\"2d\");\n",
  9317. "\n",
  9318. " var backingStore = this.context.backingStorePixelRatio ||\n",
  9319. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  9320. "\tthis.context.mozBackingStorePixelRatio ||\n",
  9321. "\tthis.context.msBackingStorePixelRatio ||\n",
  9322. "\tthis.context.oBackingStorePixelRatio ||\n",
  9323. "\tthis.context.backingStorePixelRatio || 1;\n",
  9324. "\n",
  9325. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  9326. "\n",
  9327. " var rubberband = $('<canvas/>');\n",
  9328. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  9329. "\n",
  9330. " var pass_mouse_events = true;\n",
  9331. "\n",
  9332. " canvas_div.resizable({\n",
  9333. " start: function(event, ui) {\n",
  9334. " pass_mouse_events = false;\n",
  9335. " },\n",
  9336. " resize: function(event, ui) {\n",
  9337. " fig.request_resize(ui.size.width, ui.size.height);\n",
  9338. " },\n",
  9339. " stop: function(event, ui) {\n",
  9340. " pass_mouse_events = true;\n",
  9341. " fig.request_resize(ui.size.width, ui.size.height);\n",
  9342. " },\n",
  9343. " });\n",
  9344. "\n",
  9345. " function mouse_event_fn(event) {\n",
  9346. " if (pass_mouse_events)\n",
  9347. " return fig.mouse_event(event, event['data']);\n",
  9348. " }\n",
  9349. "\n",
  9350. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  9351. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  9352. " // Throttle sequential mouse events to 1 every 20ms.\n",
  9353. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  9354. "\n",
  9355. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  9356. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  9357. "\n",
  9358. " canvas_div.on(\"wheel\", function (event) {\n",
  9359. " event = event.originalEvent;\n",
  9360. " event['data'] = 'scroll'\n",
  9361. " if (event.deltaY < 0) {\n",
  9362. " event.step = 1;\n",
  9363. " } else {\n",
  9364. " event.step = -1;\n",
  9365. " }\n",
  9366. " mouse_event_fn(event);\n",
  9367. " });\n",
  9368. "\n",
  9369. " canvas_div.append(canvas);\n",
  9370. " canvas_div.append(rubberband);\n",
  9371. "\n",
  9372. " this.rubberband = rubberband;\n",
  9373. " this.rubberband_canvas = rubberband[0];\n",
  9374. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  9375. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  9376. "\n",
  9377. " this._resize_canvas = function(width, height) {\n",
  9378. " // Keep the size of the canvas, canvas container, and rubber band\n",
  9379. " // canvas in synch.\n",
  9380. " canvas_div.css('width', width)\n",
  9381. " canvas_div.css('height', height)\n",
  9382. "\n",
  9383. " canvas.attr('width', width * mpl.ratio);\n",
  9384. " canvas.attr('height', height * mpl.ratio);\n",
  9385. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  9386. "\n",
  9387. " rubberband.attr('width', width);\n",
  9388. " rubberband.attr('height', height);\n",
  9389. " }\n",
  9390. "\n",
  9391. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  9392. " // upon first draw.\n",
  9393. " this._resize_canvas(600, 600);\n",
  9394. "\n",
  9395. " // Disable right mouse context menu.\n",
  9396. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  9397. " return false;\n",
  9398. " });\n",
  9399. "\n",
  9400. " function set_focus () {\n",
  9401. " canvas.focus();\n",
  9402. " canvas_div.focus();\n",
  9403. " }\n",
  9404. "\n",
  9405. " window.setTimeout(set_focus, 100);\n",
  9406. "}\n",
  9407. "\n",
  9408. "mpl.figure.prototype._init_toolbar = function() {\n",
  9409. " var fig = this;\n",
  9410. "\n",
  9411. " var nav_element = $('<div/>')\n",
  9412. " nav_element.attr('style', 'width: 100%');\n",
  9413. " this.root.append(nav_element);\n",
  9414. "\n",
  9415. " // Define a callback function for later on.\n",
  9416. " function toolbar_event(event) {\n",
  9417. " return fig.toolbar_button_onclick(event['data']);\n",
  9418. " }\n",
  9419. " function toolbar_mouse_event(event) {\n",
  9420. " return fig.toolbar_button_onmouseover(event['data']);\n",
  9421. " }\n",
  9422. "\n",
  9423. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  9424. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  9425. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  9426. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  9427. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  9428. "\n",
  9429. " if (!name) {\n",
  9430. " // put a spacer in here.\n",
  9431. " continue;\n",
  9432. " }\n",
  9433. " var button = $('<button/>');\n",
  9434. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  9435. " 'ui-button-icon-only');\n",
  9436. " button.attr('role', 'button');\n",
  9437. " button.attr('aria-disabled', 'false');\n",
  9438. " button.click(method_name, toolbar_event);\n",
  9439. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  9440. "\n",
  9441. " var icon_img = $('<span/>');\n",
  9442. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  9443. " icon_img.addClass(image);\n",
  9444. " icon_img.addClass('ui-corner-all');\n",
  9445. "\n",
  9446. " var tooltip_span = $('<span/>');\n",
  9447. " tooltip_span.addClass('ui-button-text');\n",
  9448. " tooltip_span.html(tooltip);\n",
  9449. "\n",
  9450. " button.append(icon_img);\n",
  9451. " button.append(tooltip_span);\n",
  9452. "\n",
  9453. " nav_element.append(button);\n",
  9454. " }\n",
  9455. "\n",
  9456. " var fmt_picker_span = $('<span/>');\n",
  9457. "\n",
  9458. " var fmt_picker = $('<select/>');\n",
  9459. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  9460. " fmt_picker_span.append(fmt_picker);\n",
  9461. " nav_element.append(fmt_picker_span);\n",
  9462. " this.format_dropdown = fmt_picker[0];\n",
  9463. "\n",
  9464. " for (var ind in mpl.extensions) {\n",
  9465. " var fmt = mpl.extensions[ind];\n",
  9466. " var option = $(\n",
  9467. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  9468. " fmt_picker.append(option)\n",
  9469. " }\n",
  9470. "\n",
  9471. " // Add hover states to the ui-buttons\n",
  9472. " $( \".ui-button\" ).hover(\n",
  9473. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  9474. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  9475. " );\n",
  9476. "\n",
  9477. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  9478. " nav_element.append(status_bar);\n",
  9479. " this.message = status_bar[0];\n",
  9480. "}\n",
  9481. "\n",
  9482. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  9483. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  9484. " // which will in turn request a refresh of the image.\n",
  9485. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  9486. "}\n",
  9487. "\n",
  9488. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  9489. " properties['type'] = type;\n",
  9490. " properties['figure_id'] = this.id;\n",
  9491. " this.ws.send(JSON.stringify(properties));\n",
  9492. "}\n",
  9493. "\n",
  9494. "mpl.figure.prototype.send_draw_message = function() {\n",
  9495. " if (!this.waiting) {\n",
  9496. " this.waiting = true;\n",
  9497. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  9498. " }\n",
  9499. "}\n",
  9500. "\n",
  9501. "\n",
  9502. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  9503. " var format_dropdown = fig.format_dropdown;\n",
  9504. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  9505. " fig.ondownload(fig, format);\n",
  9506. "}\n",
  9507. "\n",
  9508. "\n",
  9509. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  9510. " var size = msg['size'];\n",
  9511. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  9512. " fig._resize_canvas(size[0], size[1]);\n",
  9513. " fig.send_message(\"refresh\", {});\n",
  9514. " };\n",
  9515. "}\n",
  9516. "\n",
  9517. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  9518. " var x0 = msg['x0'] / mpl.ratio;\n",
  9519. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  9520. " var x1 = msg['x1'] / mpl.ratio;\n",
  9521. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  9522. " x0 = Math.floor(x0) + 0.5;\n",
  9523. " y0 = Math.floor(y0) + 0.5;\n",
  9524. " x1 = Math.floor(x1) + 0.5;\n",
  9525. " y1 = Math.floor(y1) + 0.5;\n",
  9526. " var min_x = Math.min(x0, x1);\n",
  9527. " var min_y = Math.min(y0, y1);\n",
  9528. " var width = Math.abs(x1 - x0);\n",
  9529. " var height = Math.abs(y1 - y0);\n",
  9530. "\n",
  9531. " fig.rubberband_context.clearRect(\n",
  9532. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  9533. "\n",
  9534. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  9535. "}\n",
  9536. "\n",
  9537. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  9538. " // Updates the figure title.\n",
  9539. " fig.header.textContent = msg['label'];\n",
  9540. "}\n",
  9541. "\n",
  9542. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  9543. " var cursor = msg['cursor'];\n",
  9544. " switch(cursor)\n",
  9545. " {\n",
  9546. " case 0:\n",
  9547. " cursor = 'pointer';\n",
  9548. " break;\n",
  9549. " case 1:\n",
  9550. " cursor = 'default';\n",
  9551. " break;\n",
  9552. " case 2:\n",
  9553. " cursor = 'crosshair';\n",
  9554. " break;\n",
  9555. " case 3:\n",
  9556. " cursor = 'move';\n",
  9557. " break;\n",
  9558. " }\n",
  9559. " fig.rubberband_canvas.style.cursor = cursor;\n",
  9560. "}\n",
  9561. "\n",
  9562. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  9563. " fig.message.textContent = msg['message'];\n",
  9564. "}\n",
  9565. "\n",
  9566. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  9567. " // Request the server to send over a new figure.\n",
  9568. " fig.send_draw_message();\n",
  9569. "}\n",
  9570. "\n",
  9571. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  9572. " fig.image_mode = msg['mode'];\n",
  9573. "}\n",
  9574. "\n",
  9575. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  9576. " // Called whenever the canvas gets updated.\n",
  9577. " this.send_message(\"ack\", {});\n",
  9578. "}\n",
  9579. "\n",
  9580. "// A function to construct a web socket function for onmessage handling.\n",
  9581. "// Called in the figure constructor.\n",
  9582. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  9583. " return function socket_on_message(evt) {\n",
  9584. " if (evt.data instanceof Blob) {\n",
  9585. " /* FIXME: We get \"Resource interpreted as Image but\n",
  9586. " * transferred with MIME type text/plain:\" errors on\n",
  9587. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  9588. " * to be part of the websocket stream */\n",
  9589. " evt.data.type = \"image/png\";\n",
  9590. "\n",
  9591. " /* Free the memory for the previous frames */\n",
  9592. " if (fig.imageObj.src) {\n",
  9593. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  9594. " fig.imageObj.src);\n",
  9595. " }\n",
  9596. "\n",
  9597. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  9598. " evt.data);\n",
  9599. " fig.updated_canvas_event();\n",
  9600. " fig.waiting = false;\n",
  9601. " return;\n",
  9602. " }\n",
  9603. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  9604. " fig.imageObj.src = evt.data;\n",
  9605. " fig.updated_canvas_event();\n",
  9606. " fig.waiting = false;\n",
  9607. " return;\n",
  9608. " }\n",
  9609. "\n",
  9610. " var msg = JSON.parse(evt.data);\n",
  9611. " var msg_type = msg['type'];\n",
  9612. "\n",
  9613. " // Call the \"handle_{type}\" callback, which takes\n",
  9614. " // the figure and JSON message as its only arguments.\n",
  9615. " try {\n",
  9616. " var callback = fig[\"handle_\" + msg_type];\n",
  9617. " } catch (e) {\n",
  9618. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  9619. " return;\n",
  9620. " }\n",
  9621. "\n",
  9622. " if (callback) {\n",
  9623. " try {\n",
  9624. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  9625. " callback(fig, msg);\n",
  9626. " } catch (e) {\n",
  9627. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  9628. " }\n",
  9629. " }\n",
  9630. " };\n",
  9631. "}\n",
  9632. "\n",
  9633. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  9634. "mpl.findpos = function(e) {\n",
  9635. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  9636. " var targ;\n",
  9637. " if (!e)\n",
  9638. " e = window.event;\n",
  9639. " if (e.target)\n",
  9640. " targ = e.target;\n",
  9641. " else if (e.srcElement)\n",
  9642. " targ = e.srcElement;\n",
  9643. " if (targ.nodeType == 3) // defeat Safari bug\n",
  9644. " targ = targ.parentNode;\n",
  9645. "\n",
  9646. " // jQuery normalizes the pageX and pageY\n",
  9647. " // pageX,Y are the mouse positions relative to the document\n",
  9648. " // offset() returns the position of the element relative to the document\n",
  9649. " var x = e.pageX - $(targ).offset().left;\n",
  9650. " var y = e.pageY - $(targ).offset().top;\n",
  9651. "\n",
  9652. " return {\"x\": x, \"y\": y};\n",
  9653. "};\n",
  9654. "\n",
  9655. "/*\n",
  9656. " * return a copy of an object with only non-object keys\n",
  9657. " * we need this to avoid circular references\n",
  9658. " * http://stackoverflow.com/a/24161582/3208463\n",
  9659. " */\n",
  9660. "function simpleKeys (original) {\n",
  9661. " return Object.keys(original).reduce(function (obj, key) {\n",
  9662. " if (typeof original[key] !== 'object')\n",
  9663. " obj[key] = original[key]\n",
  9664. " return obj;\n",
  9665. " }, {});\n",
  9666. "}\n",
  9667. "\n",
  9668. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  9669. " var canvas_pos = mpl.findpos(event)\n",
  9670. "\n",
  9671. " if (name === 'button_press')\n",
  9672. " {\n",
  9673. " this.canvas.focus();\n",
  9674. " this.canvas_div.focus();\n",
  9675. " }\n",
  9676. "\n",
  9677. " var x = canvas_pos.x * mpl.ratio;\n",
  9678. " var y = canvas_pos.y * mpl.ratio;\n",
  9679. "\n",
  9680. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  9681. " step: event.step,\n",
  9682. " guiEvent: simpleKeys(event)});\n",
  9683. "\n",
  9684. " /* This prevents the web browser from automatically changing to\n",
  9685. " * the text insertion cursor when the button is pressed. We want\n",
  9686. " * to control all of the cursor setting manually through the\n",
  9687. " * 'cursor' event from matplotlib */\n",
  9688. " event.preventDefault();\n",
  9689. " return false;\n",
  9690. "}\n",
  9691. "\n",
  9692. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  9693. " // Handle any extra behaviour associated with a key event\n",
  9694. "}\n",
  9695. "\n",
  9696. "mpl.figure.prototype.key_event = function(event, name) {\n",
  9697. "\n",
  9698. " // Prevent repeat events\n",
  9699. " if (name == 'key_press')\n",
  9700. " {\n",
  9701. " if (event.which === this._key)\n",
  9702. " return;\n",
  9703. " else\n",
  9704. " this._key = event.which;\n",
  9705. " }\n",
  9706. " if (name == 'key_release')\n",
  9707. " this._key = null;\n",
  9708. "\n",
  9709. " var value = '';\n",
  9710. " if (event.ctrlKey && event.which != 17)\n",
  9711. " value += \"ctrl+\";\n",
  9712. " if (event.altKey && event.which != 18)\n",
  9713. " value += \"alt+\";\n",
  9714. " if (event.shiftKey && event.which != 16)\n",
  9715. " value += \"shift+\";\n",
  9716. "\n",
  9717. " value += 'k';\n",
  9718. " value += event.which.toString();\n",
  9719. "\n",
  9720. " this._key_event_extra(event, name);\n",
  9721. "\n",
  9722. " this.send_message(name, {key: value,\n",
  9723. " guiEvent: simpleKeys(event)});\n",
  9724. " return false;\n",
  9725. "}\n",
  9726. "\n",
  9727. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  9728. " if (name == 'download') {\n",
  9729. " this.handle_save(this, null);\n",
  9730. " } else {\n",
  9731. " this.send_message(\"toolbar_button\", {name: name});\n",
  9732. " }\n",
  9733. "};\n",
  9734. "\n",
  9735. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  9736. " this.message.textContent = tooltip;\n",
  9737. "};\n",
  9738. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  9739. "\n",
  9740. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  9741. "\n",
  9742. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  9743. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  9744. " // object with the appropriate methods. Currently this is a non binary\n",
  9745. " // socket, so there is still some room for performance tuning.\n",
  9746. " var ws = {};\n",
  9747. "\n",
  9748. " ws.close = function() {\n",
  9749. " comm.close()\n",
  9750. " };\n",
  9751. " ws.send = function(m) {\n",
  9752. " //console.log('sending', m);\n",
  9753. " comm.send(m);\n",
  9754. " };\n",
  9755. " // Register the callback with on_msg.\n",
  9756. " comm.on_msg(function(msg) {\n",
  9757. " //console.log('receiving', msg['content']['data'], msg);\n",
  9758. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  9759. " ws.onmessage(msg['content']['data'])\n",
  9760. " });\n",
  9761. " return ws;\n",
  9762. "}\n",
  9763. "\n",
  9764. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  9765. " // This is the function which gets called when the mpl process\n",
  9766. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  9767. "\n",
  9768. " var id = msg.content.data.id;\n",
  9769. " // Get hold of the div created by the display call when the Comm\n",
  9770. " // socket was opened in Python.\n",
  9771. " var element = $(\"#\" + id);\n",
  9772. " var ws_proxy = comm_websocket_adapter(comm)\n",
  9773. "\n",
  9774. " function ondownload(figure, format) {\n",
  9775. " window.open(figure.imageObj.src);\n",
  9776. " }\n",
  9777. "\n",
  9778. " var fig = new mpl.figure(id, ws_proxy,\n",
  9779. " ondownload,\n",
  9780. " element.get(0));\n",
  9781. "\n",
  9782. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  9783. " // web socket which is closed, not our websocket->open comm proxy.\n",
  9784. " ws_proxy.onopen();\n",
  9785. "\n",
  9786. " fig.parent_element = element.get(0);\n",
  9787. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  9788. " if (!fig.cell_info) {\n",
  9789. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  9790. " return;\n",
  9791. " }\n",
  9792. "\n",
  9793. " var output_index = fig.cell_info[2]\n",
  9794. " var cell = fig.cell_info[0];\n",
  9795. "\n",
  9796. "};\n",
  9797. "\n",
  9798. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  9799. " var width = fig.canvas.width/mpl.ratio\n",
  9800. " fig.root.unbind('remove')\n",
  9801. "\n",
  9802. " // Update the output cell to use the data from the current canvas.\n",
  9803. " fig.push_to_output();\n",
  9804. " var dataURL = fig.canvas.toDataURL();\n",
  9805. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  9806. " // the notebook keyboard shortcuts fail.\n",
  9807. " IPython.keyboard_manager.enable()\n",
  9808. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  9809. " fig.close_ws(fig, msg);\n",
  9810. "}\n",
  9811. "\n",
  9812. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  9813. " fig.send_message('closing', msg);\n",
  9814. " // fig.ws.close()\n",
  9815. "}\n",
  9816. "\n",
  9817. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  9818. " // Turn the data on the canvas into data in the output cell.\n",
  9819. " var width = this.canvas.width/mpl.ratio\n",
  9820. " var dataURL = this.canvas.toDataURL();\n",
  9821. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  9822. "}\n",
  9823. "\n",
  9824. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  9825. " // Tell IPython that the notebook contents must change.\n",
  9826. " IPython.notebook.set_dirty(true);\n",
  9827. " this.send_message(\"ack\", {});\n",
  9828. " var fig = this;\n",
  9829. " // Wait a second, then push the new image to the DOM so\n",
  9830. " // that it is saved nicely (might be nice to debounce this).\n",
  9831. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  9832. "}\n",
  9833. "\n",
  9834. "mpl.figure.prototype._init_toolbar = function() {\n",
  9835. " var fig = this;\n",
  9836. "\n",
  9837. " var nav_element = $('<div/>')\n",
  9838. " nav_element.attr('style', 'width: 100%');\n",
  9839. " this.root.append(nav_element);\n",
  9840. "\n",
  9841. " // Define a callback function for later on.\n",
  9842. " function toolbar_event(event) {\n",
  9843. " return fig.toolbar_button_onclick(event['data']);\n",
  9844. " }\n",
  9845. " function toolbar_mouse_event(event) {\n",
  9846. " return fig.toolbar_button_onmouseover(event['data']);\n",
  9847. " }\n",
  9848. "\n",
  9849. " for(var toolbar_ind in mpl.toolbar_items){\n",
  9850. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  9851. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  9852. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  9853. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  9854. "\n",
  9855. " if (!name) { continue; };\n",
  9856. "\n",
  9857. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  9858. " button.click(method_name, toolbar_event);\n",
  9859. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  9860. " nav_element.append(button);\n",
  9861. " }\n",
  9862. "\n",
  9863. " // Add the status bar.\n",
  9864. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  9865. " nav_element.append(status_bar);\n",
  9866. " this.message = status_bar[0];\n",
  9867. "\n",
  9868. " // Add the close button to the window.\n",
  9869. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  9870. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  9871. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  9872. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  9873. " buttongrp.append(button);\n",
  9874. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  9875. " titlebar.prepend(buttongrp);\n",
  9876. "}\n",
  9877. "\n",
  9878. "mpl.figure.prototype._root_extra_style = function(el){\n",
  9879. " var fig = this\n",
  9880. " el.on(\"remove\", function(){\n",
  9881. "\tfig.close_ws(fig, {});\n",
  9882. " });\n",
  9883. "}\n",
  9884. "\n",
  9885. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  9886. " // this is important to make the div 'focusable\n",
  9887. " el.attr('tabindex', 0)\n",
  9888. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  9889. " // off when our div gets focus\n",
  9890. "\n",
  9891. " // location in version 3\n",
  9892. " if (IPython.notebook.keyboard_manager) {\n",
  9893. " IPython.notebook.keyboard_manager.register_events(el);\n",
  9894. " }\n",
  9895. " else {\n",
  9896. " // location in version 2\n",
  9897. " IPython.keyboard_manager.register_events(el);\n",
  9898. " }\n",
  9899. "\n",
  9900. "}\n",
  9901. "\n",
  9902. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  9903. " var manager = IPython.notebook.keyboard_manager;\n",
  9904. " if (!manager)\n",
  9905. " manager = IPython.keyboard_manager;\n",
  9906. "\n",
  9907. " // Check for shift+enter\n",
  9908. " if (event.shiftKey && event.which == 13) {\n",
  9909. " this.canvas_div.blur();\n",
  9910. " event.shiftKey = false;\n",
  9911. " // Send a \"J\" for go to next cell\n",
  9912. " event.which = 74;\n",
  9913. " event.keyCode = 74;\n",
  9914. " manager.command_mode();\n",
  9915. " manager.handle_keydown(event);\n",
  9916. " }\n",
  9917. "}\n",
  9918. "\n",
  9919. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  9920. " fig.ondownload(fig, null);\n",
  9921. "}\n",
  9922. "\n",
  9923. "\n",
  9924. "mpl.find_output_cell = function(html_output) {\n",
  9925. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  9926. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  9927. " // IPython event is triggered only after the cells have been serialised, which for\n",
  9928. " // our purposes (turning an active figure into a static one), is too late.\n",
  9929. " var cells = IPython.notebook.get_cells();\n",
  9930. " var ncells = cells.length;\n",
  9931. " for (var i=0; i<ncells; i++) {\n",
  9932. " var cell = cells[i];\n",
  9933. " if (cell.cell_type === 'code'){\n",
  9934. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  9935. " var data = cell.output_area.outputs[j];\n",
  9936. " if (data.data) {\n",
  9937. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  9938. " data = data.data;\n",
  9939. " }\n",
  9940. " if (data['text/html'] == html_output) {\n",
  9941. " return [cell, data, j];\n",
  9942. " }\n",
  9943. " }\n",
  9944. " }\n",
  9945. " }\n",
  9946. "}\n",
  9947. "\n",
  9948. "// Register the function which deals with the matplotlib target/channel.\n",
  9949. "// The kernel may be null if the page has been refreshed.\n",
  9950. "if (IPython.notebook.kernel != null) {\n",
  9951. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  9952. "}\n"
  9953. ],
  9954. "text/plain": [
  9955. "<IPython.core.display.Javascript object>"
  9956. ]
  9957. },
  9958. "metadata": {},
  9959. "output_type": "display_data"
  9960. },
  9961. {
  9962. "data": {
  9963. "text/html": [
  9964. "<img src=\"data:image/png;base64,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yQPj/W5LsmnK73HNeH5fkt1JdmV42uHylI9/MgwwSVJ1BhjA4ljKMIRmtWfKfV6d5PYkP0jyZJL7krwzyeZVfp8rMzw98YkMrxW7J8mOOTz+xACTJJVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAEshguSXJXkU0keTPJkkseT3JXk95KcNeN+lyW5Pclj432+muTaJJtX+b2uSHLH+PEPJPlikh3r/QRGBpgkqToDDGAx/H6S5SQPJ/nbJDckuTnJD8fjn0yyacV93pDkUIYR9YkkNyZ5YLz9bTN+n6vH8/uS7E6yK8ne8djOOXweBpgkqToDDGAxXJ7kyhz7na6fS/I/GQbSb00cPy/J95M8neRVE8fPTvKF8fZv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jj7NcNJ3xuNbp9zn0vHc50/mQY8MMElSdQYYwGLZkuRLSb6R5PnjsaVMH2CPjscvmPGxDoznzxl//YLx10/MuP1LxvOPnMDjvHdGBw0wSVJzBhjAYrk+yY/z7O9qLWX6AHtmPL5lxsd6KM/+btfPj7/+zozb/9R4/ukTeJwGmCRpQ2aAASyOX0tyKMkHVhxfypk3wGbxFERJUnUGGMBi2JLhaYdfS/K8FeeWcuY9BXEWA0ySVJ0BBrAYXpSjP3D5eH1ovI834ZAkac4ZYACL4flJbprRv+XoMLopyW+P9/E29JIkzTkDDIClTH8K4sviBzFLkjTXDDAAljJ9gCXJNeO5fUl2Z/jZYXvHYztnfLwP5ujTE3eN99s3Hrt6nY/VAJMkVWeAAbCU2QMsSa5McmeGN9c4mOSeJDuO8zHfNt7u4Hi/O5Ncsf6HaoBJkrozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwABoYoBJkqozwAAWx54kyzP63oz7XJbk9iSPJXkyyVeTXJtk8yq/zxVJ7kjyeJIDSb6YZMd6H/zIAJMkVWeAASyOPUl+mGRpSu+acvs3JDmUYUR9IsmNSR7IMNhum/F7XD2e35dkd5JdSfaOx3au+zMwwCRJ5RlgAItjz9iJOC/J95M8neRVE8fPTvKFDIPqzSvusy3JU0n2j/992PlJHhzvc+maHvGxDDBJUnUGGMDi2JMTH2BvzzCYbply7vLx3J0rjl8/Hn/PGj/eWhhgkqTqDDCAxbEnyXeTvDXJdUnekeS1mf56rlszDKa3TDm3JcnBJD9K8ryJ43dl9ne5to7n9p7cQz/CAJMkVWeAASyOPZn+Bhz/leQ1K257z3julTM+1v3j+Usmjj06Hrtgxn0OjOfPOYHHeu+MDhpgkqTmDDCAxfHuDE8ffGmGEfTyJB9L8pMk/5fkFRO3/WaGsXTxjI91d479btcz47EtM+7z0Hh+6wk8VgNMkrQhM8AA2JlhGH1q4tjpHmCzeAqiJKk6AwyAizMMo/0Tx073UxBnMcAkSdUZYAC8MMMwemrimDfhkCTpFGSAAfD6DOPoaxPHvA29JEmnIAMMYDFckuQFU45vS/KfGcbRdRPHz8vwlMK1/CDml8UPYpYkadUMMIDFsJTkiSSfSfLRJO9P8skkT2YYRp9J8tMr7vPGJIcyvHbrpiQfSPLAePvbkmya8vtcM57fl2R3kl0Znna4nOHNPtbLAJMkVWeAASyG1yT5uwwD6ocZXr/1aJLPJvmdTB9TSfLqJLcn+UGGsXZfkndm+g9vPuzKDE9PfCLDa8XuSbJj3Z/BwACTJFVngAHQxACTJFVngAHQZP9Z2bx8bl4kSVJlZ2Xzyh/9AgBnrG9neF3awQz/eqj5dNA1dU0Lck1d0zO9E72e+zP8eQYAFQ7/Acb8uKbz55rOn2s6f67pfLmeAGxI/oCbP9d0/lzT+XNN5881nS/XE4ANyR9w8+eazp9rOn+u6fy5pvPlegKwIfkDbv5c0/lzTefPNZ0/13S+XE8ANiR/wM2fazp/run8uabz55rOl+sJwIbkD7j5c03nzzWdP9d0/lzT+XI9AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABbcLyS5OcnDSZ5OsifJh5Kcfxof05niTUk+nOTzSf43yXKSW49zn8uS3J7ksSRPJvlqkmuTbF7lPlckuSPJ40kOJPlikh3reNxnqguSXJXkU0kezHB9Hk9yV5LfS3LWjPu5pqt7f5J/TrI3w/V5LMmXk7w7wzWfxjVdm7dm+N//coav4WlO5vrsSPKv4+0fH+9/xbof7ZlpT45ew5V9b8Z9fJ0CsOFclOSRDH8AfjrJ+5J8bvz1A5n9l7dF8ZUM1+KJJF/P8QfYG5IcyvCH/ieS3JjhOi4nuW3Gfa4ez+9LsjvJrgx/kV5OsnPdn8GZ5fczfF4PJ/nbJDdkGP8/HI9/MsmmFfdxTY/vmST/kuFavi/DPxrck+HzfSjJhStu75quzYUZvkafyOwBdjLXZ+d4fu94+91J9o/Hrp7fwz9j7MlwHZem9K4pt/d1CsCG9I8Z/mC6ZsXxvxiPf+w5f0Rnltcm+aUMo2B7Vh9g5yX5fobvIr5q4vjZSb4w3vfNK+6zLclTGf7StW3i+PkZvkO0nOTSk3/4Z5zLk1yZY7/T9XNJ/ifD5/tbE8dd0xNz9ozj783w+X504phrujabkvxTkm9lGADTBti2rP36XDYefzDPfrbBtvHjPLXiY20Ee8ZOhK9TADakizL8gfTtHPsX4nMz/KvjwSQveI4f15lqe1YfYG8fz98y5dzl47k7Vxy/fjz+njV+vI3ougyf74cnjrmm6/OKDJ/vZyeOuaZr844kP0ny6xm+UzNtgJ3M9fmb8fjvTrnPah+v2Z6c+ADzdQrAhnRVhj+Q/nLG+cPfHfuN5+wRndm2Z/UBdut4/i1Tzm3JMGZ/lOR5E8fvyux/ld2ao09PWgR/nOHz3TVxzDVdnz/L8Pl+cOKYa3riLsnwuqPDX5NLmT7ATub6fGc8vnXKfS4dz33+ZB70GWxPku9meD3ddRnG7Wsz/fVcvk4B2JAOP53mj2ac/8h4/g+es0d0Ztue1QfY4dfcvHLG+fvH85dMHHt0PDbrtXYHxvPnrPGxttmS5L4Mn+vrJ467pmvzrgwjYVeGv7wvJ/n3JD8zcRvX9MRsSfKlJN9I8vzx2FKmD7C1Xp8X5OhrS6d5yXj+kZN43GeyPZn+Bhz/leQ1K27r6xSADenjWf0dvQ6/fuRPn7NHdGbbntUH2DfH8xfPOH93jv3X2WfGY1tm3OehzP5X8o3k8JsRfGbFcdd0bb6XZ//F9u+TvHTFbVzTE3N9kh/n2ddhKdP/P3Ot1+fnx19/Z8btf2o8//RaH/QZ7t0Znj740gwj6OUZXmf8kyT/l+Eps4f5OgVgQzLA1mZ7DLBT4Q8zfI5fT/LiFcgBhhkAAAMiSURBVOdc05Pz0iS/meG7Nw8n+dWJc67p8f1ahnff+8CK40sxwE6Fw/8A86mJY75OAdiQPAVxbbbHUxDn7fBbRv9HhndCXMk1XZ9fzPCX+Psnjrmmq9uSYbh+Lc9+fVHiKYinysUZPt/9E8d8nQKwIXkTjrXZntUHmBeNr821GT6/+5L87IzbuKbr9+UMn/NLxl+7pqt7Uaa/TmlaHxrv40041ueFGT7fpyaO+ToFYEPyNvRrsz2rDzBvm3zi/iTD5/blHB0G07im63f4B60f/llTrunqnp/kphn9W44Oo5uS/PZ4H29Dvz6vz/D5fm3imK9TADYsP4j5xG3P6gPsvAxPgVnLDw59WRbvB4f+eYbP60s59jVfK7mmx/fLGb6DsNJZOfo6zrsnjrumJ28p05+CeDLXZ9F+EPMlmf6PeduS/GeGa3HdxHFfpwBsWBfl6L+QfzrJDUk+N/76G5n9XPpF8cYkfz32Dxmuy7cmju2ccvtDGb57eFOGF/E/MN7vtiSbpvwe14zn9yXZneEtxPeOx1Z+/HY7MnxehzJ8nktTetuK+7imq7s2w8+q+myGN9a5IcnNGb5OlzP83KVfWXEf1/TkLGX6AEtO7vp8MEefFrdrvN++8djVc3zcZ4KlDK95+0ySjyZ5f5JPZvjaXR6P//SK+/g6BWDDujDJX2X4i9ozSf47w2sbzl/tTgtiKau/BmTPlPu8OsntSX6Q4S8X9yV5Z6b/sNHDrszwdJonMjzt854MY2WjWcrxX1dzx5T7uaazvTzDG+Z8JcNfOg8leTzD57uU2d9ldE3XbimzB1hyctfnbePtDo73uzPJFet/qGec1yT5uwwD6ocZXr/1aIZ/OPidTB9Tia9TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOFP8P3KN77Xvo0JEAAAAAElFTkSuQmCC\" width=\"432\">"
  9965. ],
  9966. "text/plain": [
  9967. "<IPython.core.display.HTML object>"
  9968. ]
  9969. },
  9970. "metadata": {},
  9971. "output_type": "display_data"
  9972. },
  9973. {
  9974. "name": "stdout",
  9975. "output_type": "stream",
  9976. "text": [
  9977. "0 1\n",
  9978. "470\n",
  9979. "(355, 318)\n",
  9980. "\n"
  9981. ]
  9982. },
  9983. {
  9984. "data": {
  9985. "application/javascript": [
  9986. "/* Put everything inside the global mpl namespace */\n",
  9987. "window.mpl = {};\n",
  9988. "\n",
  9989. "\n",
  9990. "mpl.get_websocket_type = function() {\n",
  9991. " if (typeof(WebSocket) !== 'undefined') {\n",
  9992. " return WebSocket;\n",
  9993. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  9994. " return MozWebSocket;\n",
  9995. " } else {\n",
  9996. " alert('Your browser does not have WebSocket support.' +\n",
  9997. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  9998. " 'Firefox 4 and 5 are also supported but you ' +\n",
  9999. " 'have to enable WebSockets in about:config.');\n",
  10000. " };\n",
  10001. "}\n",
  10002. "\n",
  10003. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  10004. " this.id = figure_id;\n",
  10005. "\n",
  10006. " this.ws = websocket;\n",
  10007. "\n",
  10008. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  10009. "\n",
  10010. " if (!this.supports_binary) {\n",
  10011. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  10012. " if (warnings) {\n",
  10013. " warnings.style.display = 'block';\n",
  10014. " warnings.textContent = (\n",
  10015. " \"This browser does not support binary websocket messages. \" +\n",
  10016. " \"Performance may be slow.\");\n",
  10017. " }\n",
  10018. " }\n",
  10019. "\n",
  10020. " this.imageObj = new Image();\n",
  10021. "\n",
  10022. " this.context = undefined;\n",
  10023. " this.message = undefined;\n",
  10024. " this.canvas = undefined;\n",
  10025. " this.rubberband_canvas = undefined;\n",
  10026. " this.rubberband_context = undefined;\n",
  10027. " this.format_dropdown = undefined;\n",
  10028. "\n",
  10029. " this.image_mode = 'full';\n",
  10030. "\n",
  10031. " this.root = $('<div/>');\n",
  10032. " this._root_extra_style(this.root)\n",
  10033. " this.root.attr('style', 'display: inline-block');\n",
  10034. "\n",
  10035. " $(parent_element).append(this.root);\n",
  10036. "\n",
  10037. " this._init_header(this);\n",
  10038. " this._init_canvas(this);\n",
  10039. " this._init_toolbar(this);\n",
  10040. "\n",
  10041. " var fig = this;\n",
  10042. "\n",
  10043. " this.waiting = false;\n",
  10044. "\n",
  10045. " this.ws.onopen = function () {\n",
  10046. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  10047. " fig.send_message(\"send_image_mode\", {});\n",
  10048. " if (mpl.ratio != 1) {\n",
  10049. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  10050. " }\n",
  10051. " fig.send_message(\"refresh\", {});\n",
  10052. " }\n",
  10053. "\n",
  10054. " this.imageObj.onload = function() {\n",
  10055. " if (fig.image_mode == 'full') {\n",
  10056. " // Full images could contain transparency (where diff images\n",
  10057. " // almost always do), so we need to clear the canvas so that\n",
  10058. " // there is no ghosting.\n",
  10059. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  10060. " }\n",
  10061. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  10062. " };\n",
  10063. "\n",
  10064. " this.imageObj.onunload = function() {\n",
  10065. " fig.ws.close();\n",
  10066. " }\n",
  10067. "\n",
  10068. " this.ws.onmessage = this._make_on_message_function(this);\n",
  10069. "\n",
  10070. " this.ondownload = ondownload;\n",
  10071. "}\n",
  10072. "\n",
  10073. "mpl.figure.prototype._init_header = function() {\n",
  10074. " var titlebar = $(\n",
  10075. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  10076. " 'ui-helper-clearfix\"/>');\n",
  10077. " var titletext = $(\n",
  10078. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  10079. " 'text-align: center; padding: 3px;\"/>');\n",
  10080. " titlebar.append(titletext)\n",
  10081. " this.root.append(titlebar);\n",
  10082. " this.header = titletext[0];\n",
  10083. "}\n",
  10084. "\n",
  10085. "\n",
  10086. "\n",
  10087. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  10088. "\n",
  10089. "}\n",
  10090. "\n",
  10091. "\n",
  10092. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  10093. "\n",
  10094. "}\n",
  10095. "\n",
  10096. "mpl.figure.prototype._init_canvas = function() {\n",
  10097. " var fig = this;\n",
  10098. "\n",
  10099. " var canvas_div = $('<div/>');\n",
  10100. "\n",
  10101. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  10102. "\n",
  10103. " function canvas_keyboard_event(event) {\n",
  10104. " return fig.key_event(event, event['data']);\n",
  10105. " }\n",
  10106. "\n",
  10107. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  10108. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  10109. " this.canvas_div = canvas_div\n",
  10110. " this._canvas_extra_style(canvas_div)\n",
  10111. " this.root.append(canvas_div);\n",
  10112. "\n",
  10113. " var canvas = $('<canvas/>');\n",
  10114. " canvas.addClass('mpl-canvas');\n",
  10115. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  10116. "\n",
  10117. " this.canvas = canvas[0];\n",
  10118. " this.context = canvas[0].getContext(\"2d\");\n",
  10119. "\n",
  10120. " var backingStore = this.context.backingStorePixelRatio ||\n",
  10121. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  10122. "\tthis.context.mozBackingStorePixelRatio ||\n",
  10123. "\tthis.context.msBackingStorePixelRatio ||\n",
  10124. "\tthis.context.oBackingStorePixelRatio ||\n",
  10125. "\tthis.context.backingStorePixelRatio || 1;\n",
  10126. "\n",
  10127. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  10128. "\n",
  10129. " var rubberband = $('<canvas/>');\n",
  10130. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  10131. "\n",
  10132. " var pass_mouse_events = true;\n",
  10133. "\n",
  10134. " canvas_div.resizable({\n",
  10135. " start: function(event, ui) {\n",
  10136. " pass_mouse_events = false;\n",
  10137. " },\n",
  10138. " resize: function(event, ui) {\n",
  10139. " fig.request_resize(ui.size.width, ui.size.height);\n",
  10140. " },\n",
  10141. " stop: function(event, ui) {\n",
  10142. " pass_mouse_events = true;\n",
  10143. " fig.request_resize(ui.size.width, ui.size.height);\n",
  10144. " },\n",
  10145. " });\n",
  10146. "\n",
  10147. " function mouse_event_fn(event) {\n",
  10148. " if (pass_mouse_events)\n",
  10149. " return fig.mouse_event(event, event['data']);\n",
  10150. " }\n",
  10151. "\n",
  10152. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  10153. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  10154. " // Throttle sequential mouse events to 1 every 20ms.\n",
  10155. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  10156. "\n",
  10157. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  10158. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  10159. "\n",
  10160. " canvas_div.on(\"wheel\", function (event) {\n",
  10161. " event = event.originalEvent;\n",
  10162. " event['data'] = 'scroll'\n",
  10163. " if (event.deltaY < 0) {\n",
  10164. " event.step = 1;\n",
  10165. " } else {\n",
  10166. " event.step = -1;\n",
  10167. " }\n",
  10168. " mouse_event_fn(event);\n",
  10169. " });\n",
  10170. "\n",
  10171. " canvas_div.append(canvas);\n",
  10172. " canvas_div.append(rubberband);\n",
  10173. "\n",
  10174. " this.rubberband = rubberband;\n",
  10175. " this.rubberband_canvas = rubberband[0];\n",
  10176. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  10177. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  10178. "\n",
  10179. " this._resize_canvas = function(width, height) {\n",
  10180. " // Keep the size of the canvas, canvas container, and rubber band\n",
  10181. " // canvas in synch.\n",
  10182. " canvas_div.css('width', width)\n",
  10183. " canvas_div.css('height', height)\n",
  10184. "\n",
  10185. " canvas.attr('width', width * mpl.ratio);\n",
  10186. " canvas.attr('height', height * mpl.ratio);\n",
  10187. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  10188. "\n",
  10189. " rubberband.attr('width', width);\n",
  10190. " rubberband.attr('height', height);\n",
  10191. " }\n",
  10192. "\n",
  10193. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  10194. " // upon first draw.\n",
  10195. " this._resize_canvas(600, 600);\n",
  10196. "\n",
  10197. " // Disable right mouse context menu.\n",
  10198. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  10199. " return false;\n",
  10200. " });\n",
  10201. "\n",
  10202. " function set_focus () {\n",
  10203. " canvas.focus();\n",
  10204. " canvas_div.focus();\n",
  10205. " }\n",
  10206. "\n",
  10207. " window.setTimeout(set_focus, 100);\n",
  10208. "}\n",
  10209. "\n",
  10210. "mpl.figure.prototype._init_toolbar = function() {\n",
  10211. " var fig = this;\n",
  10212. "\n",
  10213. " var nav_element = $('<div/>')\n",
  10214. " nav_element.attr('style', 'width: 100%');\n",
  10215. " this.root.append(nav_element);\n",
  10216. "\n",
  10217. " // Define a callback function for later on.\n",
  10218. " function toolbar_event(event) {\n",
  10219. " return fig.toolbar_button_onclick(event['data']);\n",
  10220. " }\n",
  10221. " function toolbar_mouse_event(event) {\n",
  10222. " return fig.toolbar_button_onmouseover(event['data']);\n",
  10223. " }\n",
  10224. "\n",
  10225. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  10226. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  10227. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  10228. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  10229. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  10230. "\n",
  10231. " if (!name) {\n",
  10232. " // put a spacer in here.\n",
  10233. " continue;\n",
  10234. " }\n",
  10235. " var button = $('<button/>');\n",
  10236. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  10237. " 'ui-button-icon-only');\n",
  10238. " button.attr('role', 'button');\n",
  10239. " button.attr('aria-disabled', 'false');\n",
  10240. " button.click(method_name, toolbar_event);\n",
  10241. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  10242. "\n",
  10243. " var icon_img = $('<span/>');\n",
  10244. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  10245. " icon_img.addClass(image);\n",
  10246. " icon_img.addClass('ui-corner-all');\n",
  10247. "\n",
  10248. " var tooltip_span = $('<span/>');\n",
  10249. " tooltip_span.addClass('ui-button-text');\n",
  10250. " tooltip_span.html(tooltip);\n",
  10251. "\n",
  10252. " button.append(icon_img);\n",
  10253. " button.append(tooltip_span);\n",
  10254. "\n",
  10255. " nav_element.append(button);\n",
  10256. " }\n",
  10257. "\n",
  10258. " var fmt_picker_span = $('<span/>');\n",
  10259. "\n",
  10260. " var fmt_picker = $('<select/>');\n",
  10261. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  10262. " fmt_picker_span.append(fmt_picker);\n",
  10263. " nav_element.append(fmt_picker_span);\n",
  10264. " this.format_dropdown = fmt_picker[0];\n",
  10265. "\n",
  10266. " for (var ind in mpl.extensions) {\n",
  10267. " var fmt = mpl.extensions[ind];\n",
  10268. " var option = $(\n",
  10269. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  10270. " fmt_picker.append(option)\n",
  10271. " }\n",
  10272. "\n",
  10273. " // Add hover states to the ui-buttons\n",
  10274. " $( \".ui-button\" ).hover(\n",
  10275. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  10276. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  10277. " );\n",
  10278. "\n",
  10279. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  10280. " nav_element.append(status_bar);\n",
  10281. " this.message = status_bar[0];\n",
  10282. "}\n",
  10283. "\n",
  10284. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  10285. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  10286. " // which will in turn request a refresh of the image.\n",
  10287. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  10288. "}\n",
  10289. "\n",
  10290. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  10291. " properties['type'] = type;\n",
  10292. " properties['figure_id'] = this.id;\n",
  10293. " this.ws.send(JSON.stringify(properties));\n",
  10294. "}\n",
  10295. "\n",
  10296. "mpl.figure.prototype.send_draw_message = function() {\n",
  10297. " if (!this.waiting) {\n",
  10298. " this.waiting = true;\n",
  10299. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  10300. " }\n",
  10301. "}\n",
  10302. "\n",
  10303. "\n",
  10304. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  10305. " var format_dropdown = fig.format_dropdown;\n",
  10306. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  10307. " fig.ondownload(fig, format);\n",
  10308. "}\n",
  10309. "\n",
  10310. "\n",
  10311. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  10312. " var size = msg['size'];\n",
  10313. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  10314. " fig._resize_canvas(size[0], size[1]);\n",
  10315. " fig.send_message(\"refresh\", {});\n",
  10316. " };\n",
  10317. "}\n",
  10318. "\n",
  10319. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  10320. " var x0 = msg['x0'] / mpl.ratio;\n",
  10321. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  10322. " var x1 = msg['x1'] / mpl.ratio;\n",
  10323. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  10324. " x0 = Math.floor(x0) + 0.5;\n",
  10325. " y0 = Math.floor(y0) + 0.5;\n",
  10326. " x1 = Math.floor(x1) + 0.5;\n",
  10327. " y1 = Math.floor(y1) + 0.5;\n",
  10328. " var min_x = Math.min(x0, x1);\n",
  10329. " var min_y = Math.min(y0, y1);\n",
  10330. " var width = Math.abs(x1 - x0);\n",
  10331. " var height = Math.abs(y1 - y0);\n",
  10332. "\n",
  10333. " fig.rubberband_context.clearRect(\n",
  10334. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  10335. "\n",
  10336. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  10337. "}\n",
  10338. "\n",
  10339. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  10340. " // Updates the figure title.\n",
  10341. " fig.header.textContent = msg['label'];\n",
  10342. "}\n",
  10343. "\n",
  10344. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  10345. " var cursor = msg['cursor'];\n",
  10346. " switch(cursor)\n",
  10347. " {\n",
  10348. " case 0:\n",
  10349. " cursor = 'pointer';\n",
  10350. " break;\n",
  10351. " case 1:\n",
  10352. " cursor = 'default';\n",
  10353. " break;\n",
  10354. " case 2:\n",
  10355. " cursor = 'crosshair';\n",
  10356. " break;\n",
  10357. " case 3:\n",
  10358. " cursor = 'move';\n",
  10359. " break;\n",
  10360. " }\n",
  10361. " fig.rubberband_canvas.style.cursor = cursor;\n",
  10362. "}\n",
  10363. "\n",
  10364. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  10365. " fig.message.textContent = msg['message'];\n",
  10366. "}\n",
  10367. "\n",
  10368. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  10369. " // Request the server to send over a new figure.\n",
  10370. " fig.send_draw_message();\n",
  10371. "}\n",
  10372. "\n",
  10373. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  10374. " fig.image_mode = msg['mode'];\n",
  10375. "}\n",
  10376. "\n",
  10377. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  10378. " // Called whenever the canvas gets updated.\n",
  10379. " this.send_message(\"ack\", {});\n",
  10380. "}\n",
  10381. "\n",
  10382. "// A function to construct a web socket function for onmessage handling.\n",
  10383. "// Called in the figure constructor.\n",
  10384. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  10385. " return function socket_on_message(evt) {\n",
  10386. " if (evt.data instanceof Blob) {\n",
  10387. " /* FIXME: We get \"Resource interpreted as Image but\n",
  10388. " * transferred with MIME type text/plain:\" errors on\n",
  10389. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  10390. " * to be part of the websocket stream */\n",
  10391. " evt.data.type = \"image/png\";\n",
  10392. "\n",
  10393. " /* Free the memory for the previous frames */\n",
  10394. " if (fig.imageObj.src) {\n",
  10395. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  10396. " fig.imageObj.src);\n",
  10397. " }\n",
  10398. "\n",
  10399. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  10400. " evt.data);\n",
  10401. " fig.updated_canvas_event();\n",
  10402. " fig.waiting = false;\n",
  10403. " return;\n",
  10404. " }\n",
  10405. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  10406. " fig.imageObj.src = evt.data;\n",
  10407. " fig.updated_canvas_event();\n",
  10408. " fig.waiting = false;\n",
  10409. " return;\n",
  10410. " }\n",
  10411. "\n",
  10412. " var msg = JSON.parse(evt.data);\n",
  10413. " var msg_type = msg['type'];\n",
  10414. "\n",
  10415. " // Call the \"handle_{type}\" callback, which takes\n",
  10416. " // the figure and JSON message as its only arguments.\n",
  10417. " try {\n",
  10418. " var callback = fig[\"handle_\" + msg_type];\n",
  10419. " } catch (e) {\n",
  10420. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  10421. " return;\n",
  10422. " }\n",
  10423. "\n",
  10424. " if (callback) {\n",
  10425. " try {\n",
  10426. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  10427. " callback(fig, msg);\n",
  10428. " } catch (e) {\n",
  10429. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  10430. " }\n",
  10431. " }\n",
  10432. " };\n",
  10433. "}\n",
  10434. "\n",
  10435. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  10436. "mpl.findpos = function(e) {\n",
  10437. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  10438. " var targ;\n",
  10439. " if (!e)\n",
  10440. " e = window.event;\n",
  10441. " if (e.target)\n",
  10442. " targ = e.target;\n",
  10443. " else if (e.srcElement)\n",
  10444. " targ = e.srcElement;\n",
  10445. " if (targ.nodeType == 3) // defeat Safari bug\n",
  10446. " targ = targ.parentNode;\n",
  10447. "\n",
  10448. " // jQuery normalizes the pageX and pageY\n",
  10449. " // pageX,Y are the mouse positions relative to the document\n",
  10450. " // offset() returns the position of the element relative to the document\n",
  10451. " var x = e.pageX - $(targ).offset().left;\n",
  10452. " var y = e.pageY - $(targ).offset().top;\n",
  10453. "\n",
  10454. " return {\"x\": x, \"y\": y};\n",
  10455. "};\n",
  10456. "\n",
  10457. "/*\n",
  10458. " * return a copy of an object with only non-object keys\n",
  10459. " * we need this to avoid circular references\n",
  10460. " * http://stackoverflow.com/a/24161582/3208463\n",
  10461. " */\n",
  10462. "function simpleKeys (original) {\n",
  10463. " return Object.keys(original).reduce(function (obj, key) {\n",
  10464. " if (typeof original[key] !== 'object')\n",
  10465. " obj[key] = original[key]\n",
  10466. " return obj;\n",
  10467. " }, {});\n",
  10468. "}\n",
  10469. "\n",
  10470. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  10471. " var canvas_pos = mpl.findpos(event)\n",
  10472. "\n",
  10473. " if (name === 'button_press')\n",
  10474. " {\n",
  10475. " this.canvas.focus();\n",
  10476. " this.canvas_div.focus();\n",
  10477. " }\n",
  10478. "\n",
  10479. " var x = canvas_pos.x * mpl.ratio;\n",
  10480. " var y = canvas_pos.y * mpl.ratio;\n",
  10481. "\n",
  10482. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  10483. " step: event.step,\n",
  10484. " guiEvent: simpleKeys(event)});\n",
  10485. "\n",
  10486. " /* This prevents the web browser from automatically changing to\n",
  10487. " * the text insertion cursor when the button is pressed. We want\n",
  10488. " * to control all of the cursor setting manually through the\n",
  10489. " * 'cursor' event from matplotlib */\n",
  10490. " event.preventDefault();\n",
  10491. " return false;\n",
  10492. "}\n",
  10493. "\n",
  10494. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  10495. " // Handle any extra behaviour associated with a key event\n",
  10496. "}\n",
  10497. "\n",
  10498. "mpl.figure.prototype.key_event = function(event, name) {\n",
  10499. "\n",
  10500. " // Prevent repeat events\n",
  10501. " if (name == 'key_press')\n",
  10502. " {\n",
  10503. " if (event.which === this._key)\n",
  10504. " return;\n",
  10505. " else\n",
  10506. " this._key = event.which;\n",
  10507. " }\n",
  10508. " if (name == 'key_release')\n",
  10509. " this._key = null;\n",
  10510. "\n",
  10511. " var value = '';\n",
  10512. " if (event.ctrlKey && event.which != 17)\n",
  10513. " value += \"ctrl+\";\n",
  10514. " if (event.altKey && event.which != 18)\n",
  10515. " value += \"alt+\";\n",
  10516. " if (event.shiftKey && event.which != 16)\n",
  10517. " value += \"shift+\";\n",
  10518. "\n",
  10519. " value += 'k';\n",
  10520. " value += event.which.toString();\n",
  10521. "\n",
  10522. " this._key_event_extra(event, name);\n",
  10523. "\n",
  10524. " this.send_message(name, {key: value,\n",
  10525. " guiEvent: simpleKeys(event)});\n",
  10526. " return false;\n",
  10527. "}\n",
  10528. "\n",
  10529. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  10530. " if (name == 'download') {\n",
  10531. " this.handle_save(this, null);\n",
  10532. " } else {\n",
  10533. " this.send_message(\"toolbar_button\", {name: name});\n",
  10534. " }\n",
  10535. "};\n",
  10536. "\n",
  10537. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  10538. " this.message.textContent = tooltip;\n",
  10539. "};\n",
  10540. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  10541. "\n",
  10542. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  10543. "\n",
  10544. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  10545. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  10546. " // object with the appropriate methods. Currently this is a non binary\n",
  10547. " // socket, so there is still some room for performance tuning.\n",
  10548. " var ws = {};\n",
  10549. "\n",
  10550. " ws.close = function() {\n",
  10551. " comm.close()\n",
  10552. " };\n",
  10553. " ws.send = function(m) {\n",
  10554. " //console.log('sending', m);\n",
  10555. " comm.send(m);\n",
  10556. " };\n",
  10557. " // Register the callback with on_msg.\n",
  10558. " comm.on_msg(function(msg) {\n",
  10559. " //console.log('receiving', msg['content']['data'], msg);\n",
  10560. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  10561. " ws.onmessage(msg['content']['data'])\n",
  10562. " });\n",
  10563. " return ws;\n",
  10564. "}\n",
  10565. "\n",
  10566. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  10567. " // This is the function which gets called when the mpl process\n",
  10568. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  10569. "\n",
  10570. " var id = msg.content.data.id;\n",
  10571. " // Get hold of the div created by the display call when the Comm\n",
  10572. " // socket was opened in Python.\n",
  10573. " var element = $(\"#\" + id);\n",
  10574. " var ws_proxy = comm_websocket_adapter(comm)\n",
  10575. "\n",
  10576. " function ondownload(figure, format) {\n",
  10577. " window.open(figure.imageObj.src);\n",
  10578. " }\n",
  10579. "\n",
  10580. " var fig = new mpl.figure(id, ws_proxy,\n",
  10581. " ondownload,\n",
  10582. " element.get(0));\n",
  10583. "\n",
  10584. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  10585. " // web socket which is closed, not our websocket->open comm proxy.\n",
  10586. " ws_proxy.onopen();\n",
  10587. "\n",
  10588. " fig.parent_element = element.get(0);\n",
  10589. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  10590. " if (!fig.cell_info) {\n",
  10591. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  10592. " return;\n",
  10593. " }\n",
  10594. "\n",
  10595. " var output_index = fig.cell_info[2]\n",
  10596. " var cell = fig.cell_info[0];\n",
  10597. "\n",
  10598. "};\n",
  10599. "\n",
  10600. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  10601. " var width = fig.canvas.width/mpl.ratio\n",
  10602. " fig.root.unbind('remove')\n",
  10603. "\n",
  10604. " // Update the output cell to use the data from the current canvas.\n",
  10605. " fig.push_to_output();\n",
  10606. " var dataURL = fig.canvas.toDataURL();\n",
  10607. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  10608. " // the notebook keyboard shortcuts fail.\n",
  10609. " IPython.keyboard_manager.enable()\n",
  10610. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  10611. " fig.close_ws(fig, msg);\n",
  10612. "}\n",
  10613. "\n",
  10614. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  10615. " fig.send_message('closing', msg);\n",
  10616. " // fig.ws.close()\n",
  10617. "}\n",
  10618. "\n",
  10619. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  10620. " // Turn the data on the canvas into data in the output cell.\n",
  10621. " var width = this.canvas.width/mpl.ratio\n",
  10622. " var dataURL = this.canvas.toDataURL();\n",
  10623. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  10624. "}\n",
  10625. "\n",
  10626. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  10627. " // Tell IPython that the notebook contents must change.\n",
  10628. " IPython.notebook.set_dirty(true);\n",
  10629. " this.send_message(\"ack\", {});\n",
  10630. " var fig = this;\n",
  10631. " // Wait a second, then push the new image to the DOM so\n",
  10632. " // that it is saved nicely (might be nice to debounce this).\n",
  10633. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  10634. "}\n",
  10635. "\n",
  10636. "mpl.figure.prototype._init_toolbar = function() {\n",
  10637. " var fig = this;\n",
  10638. "\n",
  10639. " var nav_element = $('<div/>')\n",
  10640. " nav_element.attr('style', 'width: 100%');\n",
  10641. " this.root.append(nav_element);\n",
  10642. "\n",
  10643. " // Define a callback function for later on.\n",
  10644. " function toolbar_event(event) {\n",
  10645. " return fig.toolbar_button_onclick(event['data']);\n",
  10646. " }\n",
  10647. " function toolbar_mouse_event(event) {\n",
  10648. " return fig.toolbar_button_onmouseover(event['data']);\n",
  10649. " }\n",
  10650. "\n",
  10651. " for(var toolbar_ind in mpl.toolbar_items){\n",
  10652. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  10653. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  10654. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  10655. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  10656. "\n",
  10657. " if (!name) { continue; };\n",
  10658. "\n",
  10659. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  10660. " button.click(method_name, toolbar_event);\n",
  10661. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  10662. " nav_element.append(button);\n",
  10663. " }\n",
  10664. "\n",
  10665. " // Add the status bar.\n",
  10666. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  10667. " nav_element.append(status_bar);\n",
  10668. " this.message = status_bar[0];\n",
  10669. "\n",
  10670. " // Add the close button to the window.\n",
  10671. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  10672. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  10673. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  10674. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  10675. " buttongrp.append(button);\n",
  10676. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  10677. " titlebar.prepend(buttongrp);\n",
  10678. "}\n",
  10679. "\n",
  10680. "mpl.figure.prototype._root_extra_style = function(el){\n",
  10681. " var fig = this\n",
  10682. " el.on(\"remove\", function(){\n",
  10683. "\tfig.close_ws(fig, {});\n",
  10684. " });\n",
  10685. "}\n",
  10686. "\n",
  10687. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  10688. " // this is important to make the div 'focusable\n",
  10689. " el.attr('tabindex', 0)\n",
  10690. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  10691. " // off when our div gets focus\n",
  10692. "\n",
  10693. " // location in version 3\n",
  10694. " if (IPython.notebook.keyboard_manager) {\n",
  10695. " IPython.notebook.keyboard_manager.register_events(el);\n",
  10696. " }\n",
  10697. " else {\n",
  10698. " // location in version 2\n",
  10699. " IPython.keyboard_manager.register_events(el);\n",
  10700. " }\n",
  10701. "\n",
  10702. "}\n",
  10703. "\n",
  10704. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  10705. " var manager = IPython.notebook.keyboard_manager;\n",
  10706. " if (!manager)\n",
  10707. " manager = IPython.keyboard_manager;\n",
  10708. "\n",
  10709. " // Check for shift+enter\n",
  10710. " if (event.shiftKey && event.which == 13) {\n",
  10711. " this.canvas_div.blur();\n",
  10712. " event.shiftKey = false;\n",
  10713. " // Send a \"J\" for go to next cell\n",
  10714. " event.which = 74;\n",
  10715. " event.keyCode = 74;\n",
  10716. " manager.command_mode();\n",
  10717. " manager.handle_keydown(event);\n",
  10718. " }\n",
  10719. "}\n",
  10720. "\n",
  10721. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  10722. " fig.ondownload(fig, null);\n",
  10723. "}\n",
  10724. "\n",
  10725. "\n",
  10726. "mpl.find_output_cell = function(html_output) {\n",
  10727. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  10728. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  10729. " // IPython event is triggered only after the cells have been serialised, which for\n",
  10730. " // our purposes (turning an active figure into a static one), is too late.\n",
  10731. " var cells = IPython.notebook.get_cells();\n",
  10732. " var ncells = cells.length;\n",
  10733. " for (var i=0; i<ncells; i++) {\n",
  10734. " var cell = cells[i];\n",
  10735. " if (cell.cell_type === 'code'){\n",
  10736. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  10737. " var data = cell.output_area.outputs[j];\n",
  10738. " if (data.data) {\n",
  10739. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  10740. " data = data.data;\n",
  10741. " }\n",
  10742. " if (data['text/html'] == html_output) {\n",
  10743. " return [cell, data, j];\n",
  10744. " }\n",
  10745. " }\n",
  10746. " }\n",
  10747. " }\n",
  10748. "}\n",
  10749. "\n",
  10750. "// Register the function which deals with the matplotlib target/channel.\n",
  10751. "// The kernel may be null if the page has been refreshed.\n",
  10752. "if (IPython.notebook.kernel != null) {\n",
  10753. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  10754. "}\n"
  10755. ],
  10756. "text/plain": [
  10757. "<IPython.core.display.Javascript object>"
  10758. ]
  10759. },
  10760. "metadata": {},
  10761. "output_type": "display_data"
  10762. },
  10763. {
  10764. "data": {
  10765. "text/html": [
  10766. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  10767. ],
  10768. "text/plain": [
  10769. "<IPython.core.display.HTML object>"
  10770. ]
  10771. },
  10772. "metadata": {},
  10773. "output_type": "display_data"
  10774. },
  10775. {
  10776. "name": "stdout",
  10777. "output_type": "stream",
  10778. "text": [
  10779. "0.0 0.99999726\n",
  10780. "456.60754\n",
  10781. "(368, 316)\n",
  10782. "\n"
  10783. ]
  10784. },
  10785. {
  10786. "data": {
  10787. "application/javascript": [
  10788. "/* Put everything inside the global mpl namespace */\n",
  10789. "window.mpl = {};\n",
  10790. "\n",
  10791. "\n",
  10792. "mpl.get_websocket_type = function() {\n",
  10793. " if (typeof(WebSocket) !== 'undefined') {\n",
  10794. " return WebSocket;\n",
  10795. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  10796. " return MozWebSocket;\n",
  10797. " } else {\n",
  10798. " alert('Your browser does not have WebSocket support.' +\n",
  10799. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  10800. " 'Firefox 4 and 5 are also supported but you ' +\n",
  10801. " 'have to enable WebSockets in about:config.');\n",
  10802. " };\n",
  10803. "}\n",
  10804. "\n",
  10805. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  10806. " this.id = figure_id;\n",
  10807. "\n",
  10808. " this.ws = websocket;\n",
  10809. "\n",
  10810. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  10811. "\n",
  10812. " if (!this.supports_binary) {\n",
  10813. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  10814. " if (warnings) {\n",
  10815. " warnings.style.display = 'block';\n",
  10816. " warnings.textContent = (\n",
  10817. " \"This browser does not support binary websocket messages. \" +\n",
  10818. " \"Performance may be slow.\");\n",
  10819. " }\n",
  10820. " }\n",
  10821. "\n",
  10822. " this.imageObj = new Image();\n",
  10823. "\n",
  10824. " this.context = undefined;\n",
  10825. " this.message = undefined;\n",
  10826. " this.canvas = undefined;\n",
  10827. " this.rubberband_canvas = undefined;\n",
  10828. " this.rubberband_context = undefined;\n",
  10829. " this.format_dropdown = undefined;\n",
  10830. "\n",
  10831. " this.image_mode = 'full';\n",
  10832. "\n",
  10833. " this.root = $('<div/>');\n",
  10834. " this._root_extra_style(this.root)\n",
  10835. " this.root.attr('style', 'display: inline-block');\n",
  10836. "\n",
  10837. " $(parent_element).append(this.root);\n",
  10838. "\n",
  10839. " this._init_header(this);\n",
  10840. " this._init_canvas(this);\n",
  10841. " this._init_toolbar(this);\n",
  10842. "\n",
  10843. " var fig = this;\n",
  10844. "\n",
  10845. " this.waiting = false;\n",
  10846. "\n",
  10847. " this.ws.onopen = function () {\n",
  10848. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  10849. " fig.send_message(\"send_image_mode\", {});\n",
  10850. " if (mpl.ratio != 1) {\n",
  10851. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  10852. " }\n",
  10853. " fig.send_message(\"refresh\", {});\n",
  10854. " }\n",
  10855. "\n",
  10856. " this.imageObj.onload = function() {\n",
  10857. " if (fig.image_mode == 'full') {\n",
  10858. " // Full images could contain transparency (where diff images\n",
  10859. " // almost always do), so we need to clear the canvas so that\n",
  10860. " // there is no ghosting.\n",
  10861. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  10862. " }\n",
  10863. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  10864. " };\n",
  10865. "\n",
  10866. " this.imageObj.onunload = function() {\n",
  10867. " fig.ws.close();\n",
  10868. " }\n",
  10869. "\n",
  10870. " this.ws.onmessage = this._make_on_message_function(this);\n",
  10871. "\n",
  10872. " this.ondownload = ondownload;\n",
  10873. "}\n",
  10874. "\n",
  10875. "mpl.figure.prototype._init_header = function() {\n",
  10876. " var titlebar = $(\n",
  10877. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  10878. " 'ui-helper-clearfix\"/>');\n",
  10879. " var titletext = $(\n",
  10880. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  10881. " 'text-align: center; padding: 3px;\"/>');\n",
  10882. " titlebar.append(titletext)\n",
  10883. " this.root.append(titlebar);\n",
  10884. " this.header = titletext[0];\n",
  10885. "}\n",
  10886. "\n",
  10887. "\n",
  10888. "\n",
  10889. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  10890. "\n",
  10891. "}\n",
  10892. "\n",
  10893. "\n",
  10894. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  10895. "\n",
  10896. "}\n",
  10897. "\n",
  10898. "mpl.figure.prototype._init_canvas = function() {\n",
  10899. " var fig = this;\n",
  10900. "\n",
  10901. " var canvas_div = $('<div/>');\n",
  10902. "\n",
  10903. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  10904. "\n",
  10905. " function canvas_keyboard_event(event) {\n",
  10906. " return fig.key_event(event, event['data']);\n",
  10907. " }\n",
  10908. "\n",
  10909. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  10910. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  10911. " this.canvas_div = canvas_div\n",
  10912. " this._canvas_extra_style(canvas_div)\n",
  10913. " this.root.append(canvas_div);\n",
  10914. "\n",
  10915. " var canvas = $('<canvas/>');\n",
  10916. " canvas.addClass('mpl-canvas');\n",
  10917. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  10918. "\n",
  10919. " this.canvas = canvas[0];\n",
  10920. " this.context = canvas[0].getContext(\"2d\");\n",
  10921. "\n",
  10922. " var backingStore = this.context.backingStorePixelRatio ||\n",
  10923. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  10924. "\tthis.context.mozBackingStorePixelRatio ||\n",
  10925. "\tthis.context.msBackingStorePixelRatio ||\n",
  10926. "\tthis.context.oBackingStorePixelRatio ||\n",
  10927. "\tthis.context.backingStorePixelRatio || 1;\n",
  10928. "\n",
  10929. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  10930. "\n",
  10931. " var rubberband = $('<canvas/>');\n",
  10932. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  10933. "\n",
  10934. " var pass_mouse_events = true;\n",
  10935. "\n",
  10936. " canvas_div.resizable({\n",
  10937. " start: function(event, ui) {\n",
  10938. " pass_mouse_events = false;\n",
  10939. " },\n",
  10940. " resize: function(event, ui) {\n",
  10941. " fig.request_resize(ui.size.width, ui.size.height);\n",
  10942. " },\n",
  10943. " stop: function(event, ui) {\n",
  10944. " pass_mouse_events = true;\n",
  10945. " fig.request_resize(ui.size.width, ui.size.height);\n",
  10946. " },\n",
  10947. " });\n",
  10948. "\n",
  10949. " function mouse_event_fn(event) {\n",
  10950. " if (pass_mouse_events)\n",
  10951. " return fig.mouse_event(event, event['data']);\n",
  10952. " }\n",
  10953. "\n",
  10954. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  10955. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  10956. " // Throttle sequential mouse events to 1 every 20ms.\n",
  10957. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  10958. "\n",
  10959. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  10960. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  10961. "\n",
  10962. " canvas_div.on(\"wheel\", function (event) {\n",
  10963. " event = event.originalEvent;\n",
  10964. " event['data'] = 'scroll'\n",
  10965. " if (event.deltaY < 0) {\n",
  10966. " event.step = 1;\n",
  10967. " } else {\n",
  10968. " event.step = -1;\n",
  10969. " }\n",
  10970. " mouse_event_fn(event);\n",
  10971. " });\n",
  10972. "\n",
  10973. " canvas_div.append(canvas);\n",
  10974. " canvas_div.append(rubberband);\n",
  10975. "\n",
  10976. " this.rubberband = rubberband;\n",
  10977. " this.rubberband_canvas = rubberband[0];\n",
  10978. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  10979. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  10980. "\n",
  10981. " this._resize_canvas = function(width, height) {\n",
  10982. " // Keep the size of the canvas, canvas container, and rubber band\n",
  10983. " // canvas in synch.\n",
  10984. " canvas_div.css('width', width)\n",
  10985. " canvas_div.css('height', height)\n",
  10986. "\n",
  10987. " canvas.attr('width', width * mpl.ratio);\n",
  10988. " canvas.attr('height', height * mpl.ratio);\n",
  10989. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  10990. "\n",
  10991. " rubberband.attr('width', width);\n",
  10992. " rubberband.attr('height', height);\n",
  10993. " }\n",
  10994. "\n",
  10995. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  10996. " // upon first draw.\n",
  10997. " this._resize_canvas(600, 600);\n",
  10998. "\n",
  10999. " // Disable right mouse context menu.\n",
  11000. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  11001. " return false;\n",
  11002. " });\n",
  11003. "\n",
  11004. " function set_focus () {\n",
  11005. " canvas.focus();\n",
  11006. " canvas_div.focus();\n",
  11007. " }\n",
  11008. "\n",
  11009. " window.setTimeout(set_focus, 100);\n",
  11010. "}\n",
  11011. "\n",
  11012. "mpl.figure.prototype._init_toolbar = function() {\n",
  11013. " var fig = this;\n",
  11014. "\n",
  11015. " var nav_element = $('<div/>')\n",
  11016. " nav_element.attr('style', 'width: 100%');\n",
  11017. " this.root.append(nav_element);\n",
  11018. "\n",
  11019. " // Define a callback function for later on.\n",
  11020. " function toolbar_event(event) {\n",
  11021. " return fig.toolbar_button_onclick(event['data']);\n",
  11022. " }\n",
  11023. " function toolbar_mouse_event(event) {\n",
  11024. " return fig.toolbar_button_onmouseover(event['data']);\n",
  11025. " }\n",
  11026. "\n",
  11027. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  11028. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  11029. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  11030. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  11031. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  11032. "\n",
  11033. " if (!name) {\n",
  11034. " // put a spacer in here.\n",
  11035. " continue;\n",
  11036. " }\n",
  11037. " var button = $('<button/>');\n",
  11038. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  11039. " 'ui-button-icon-only');\n",
  11040. " button.attr('role', 'button');\n",
  11041. " button.attr('aria-disabled', 'false');\n",
  11042. " button.click(method_name, toolbar_event);\n",
  11043. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  11044. "\n",
  11045. " var icon_img = $('<span/>');\n",
  11046. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  11047. " icon_img.addClass(image);\n",
  11048. " icon_img.addClass('ui-corner-all');\n",
  11049. "\n",
  11050. " var tooltip_span = $('<span/>');\n",
  11051. " tooltip_span.addClass('ui-button-text');\n",
  11052. " tooltip_span.html(tooltip);\n",
  11053. "\n",
  11054. " button.append(icon_img);\n",
  11055. " button.append(tooltip_span);\n",
  11056. "\n",
  11057. " nav_element.append(button);\n",
  11058. " }\n",
  11059. "\n",
  11060. " var fmt_picker_span = $('<span/>');\n",
  11061. "\n",
  11062. " var fmt_picker = $('<select/>');\n",
  11063. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  11064. " fmt_picker_span.append(fmt_picker);\n",
  11065. " nav_element.append(fmt_picker_span);\n",
  11066. " this.format_dropdown = fmt_picker[0];\n",
  11067. "\n",
  11068. " for (var ind in mpl.extensions) {\n",
  11069. " var fmt = mpl.extensions[ind];\n",
  11070. " var option = $(\n",
  11071. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  11072. " fmt_picker.append(option)\n",
  11073. " }\n",
  11074. "\n",
  11075. " // Add hover states to the ui-buttons\n",
  11076. " $( \".ui-button\" ).hover(\n",
  11077. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  11078. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  11079. " );\n",
  11080. "\n",
  11081. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  11082. " nav_element.append(status_bar);\n",
  11083. " this.message = status_bar[0];\n",
  11084. "}\n",
  11085. "\n",
  11086. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  11087. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  11088. " // which will in turn request a refresh of the image.\n",
  11089. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  11090. "}\n",
  11091. "\n",
  11092. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  11093. " properties['type'] = type;\n",
  11094. " properties['figure_id'] = this.id;\n",
  11095. " this.ws.send(JSON.stringify(properties));\n",
  11096. "}\n",
  11097. "\n",
  11098. "mpl.figure.prototype.send_draw_message = function() {\n",
  11099. " if (!this.waiting) {\n",
  11100. " this.waiting = true;\n",
  11101. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  11102. " }\n",
  11103. "}\n",
  11104. "\n",
  11105. "\n",
  11106. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  11107. " var format_dropdown = fig.format_dropdown;\n",
  11108. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  11109. " fig.ondownload(fig, format);\n",
  11110. "}\n",
  11111. "\n",
  11112. "\n",
  11113. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  11114. " var size = msg['size'];\n",
  11115. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  11116. " fig._resize_canvas(size[0], size[1]);\n",
  11117. " fig.send_message(\"refresh\", {});\n",
  11118. " };\n",
  11119. "}\n",
  11120. "\n",
  11121. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  11122. " var x0 = msg['x0'] / mpl.ratio;\n",
  11123. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  11124. " var x1 = msg['x1'] / mpl.ratio;\n",
  11125. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  11126. " x0 = Math.floor(x0) + 0.5;\n",
  11127. " y0 = Math.floor(y0) + 0.5;\n",
  11128. " x1 = Math.floor(x1) + 0.5;\n",
  11129. " y1 = Math.floor(y1) + 0.5;\n",
  11130. " var min_x = Math.min(x0, x1);\n",
  11131. " var min_y = Math.min(y0, y1);\n",
  11132. " var width = Math.abs(x1 - x0);\n",
  11133. " var height = Math.abs(y1 - y0);\n",
  11134. "\n",
  11135. " fig.rubberband_context.clearRect(\n",
  11136. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  11137. "\n",
  11138. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  11139. "}\n",
  11140. "\n",
  11141. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  11142. " // Updates the figure title.\n",
  11143. " fig.header.textContent = msg['label'];\n",
  11144. "}\n",
  11145. "\n",
  11146. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  11147. " var cursor = msg['cursor'];\n",
  11148. " switch(cursor)\n",
  11149. " {\n",
  11150. " case 0:\n",
  11151. " cursor = 'pointer';\n",
  11152. " break;\n",
  11153. " case 1:\n",
  11154. " cursor = 'default';\n",
  11155. " break;\n",
  11156. " case 2:\n",
  11157. " cursor = 'crosshair';\n",
  11158. " break;\n",
  11159. " case 3:\n",
  11160. " cursor = 'move';\n",
  11161. " break;\n",
  11162. " }\n",
  11163. " fig.rubberband_canvas.style.cursor = cursor;\n",
  11164. "}\n",
  11165. "\n",
  11166. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  11167. " fig.message.textContent = msg['message'];\n",
  11168. "}\n",
  11169. "\n",
  11170. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  11171. " // Request the server to send over a new figure.\n",
  11172. " fig.send_draw_message();\n",
  11173. "}\n",
  11174. "\n",
  11175. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  11176. " fig.image_mode = msg['mode'];\n",
  11177. "}\n",
  11178. "\n",
  11179. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  11180. " // Called whenever the canvas gets updated.\n",
  11181. " this.send_message(\"ack\", {});\n",
  11182. "}\n",
  11183. "\n",
  11184. "// A function to construct a web socket function for onmessage handling.\n",
  11185. "// Called in the figure constructor.\n",
  11186. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  11187. " return function socket_on_message(evt) {\n",
  11188. " if (evt.data instanceof Blob) {\n",
  11189. " /* FIXME: We get \"Resource interpreted as Image but\n",
  11190. " * transferred with MIME type text/plain:\" errors on\n",
  11191. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  11192. " * to be part of the websocket stream */\n",
  11193. " evt.data.type = \"image/png\";\n",
  11194. "\n",
  11195. " /* Free the memory for the previous frames */\n",
  11196. " if (fig.imageObj.src) {\n",
  11197. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  11198. " fig.imageObj.src);\n",
  11199. " }\n",
  11200. "\n",
  11201. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  11202. " evt.data);\n",
  11203. " fig.updated_canvas_event();\n",
  11204. " fig.waiting = false;\n",
  11205. " return;\n",
  11206. " }\n",
  11207. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  11208. " fig.imageObj.src = evt.data;\n",
  11209. " fig.updated_canvas_event();\n",
  11210. " fig.waiting = false;\n",
  11211. " return;\n",
  11212. " }\n",
  11213. "\n",
  11214. " var msg = JSON.parse(evt.data);\n",
  11215. " var msg_type = msg['type'];\n",
  11216. "\n",
  11217. " // Call the \"handle_{type}\" callback, which takes\n",
  11218. " // the figure and JSON message as its only arguments.\n",
  11219. " try {\n",
  11220. " var callback = fig[\"handle_\" + msg_type];\n",
  11221. " } catch (e) {\n",
  11222. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  11223. " return;\n",
  11224. " }\n",
  11225. "\n",
  11226. " if (callback) {\n",
  11227. " try {\n",
  11228. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  11229. " callback(fig, msg);\n",
  11230. " } catch (e) {\n",
  11231. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  11232. " }\n",
  11233. " }\n",
  11234. " };\n",
  11235. "}\n",
  11236. "\n",
  11237. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  11238. "mpl.findpos = function(e) {\n",
  11239. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  11240. " var targ;\n",
  11241. " if (!e)\n",
  11242. " e = window.event;\n",
  11243. " if (e.target)\n",
  11244. " targ = e.target;\n",
  11245. " else if (e.srcElement)\n",
  11246. " targ = e.srcElement;\n",
  11247. " if (targ.nodeType == 3) // defeat Safari bug\n",
  11248. " targ = targ.parentNode;\n",
  11249. "\n",
  11250. " // jQuery normalizes the pageX and pageY\n",
  11251. " // pageX,Y are the mouse positions relative to the document\n",
  11252. " // offset() returns the position of the element relative to the document\n",
  11253. " var x = e.pageX - $(targ).offset().left;\n",
  11254. " var y = e.pageY - $(targ).offset().top;\n",
  11255. "\n",
  11256. " return {\"x\": x, \"y\": y};\n",
  11257. "};\n",
  11258. "\n",
  11259. "/*\n",
  11260. " * return a copy of an object with only non-object keys\n",
  11261. " * we need this to avoid circular references\n",
  11262. " * http://stackoverflow.com/a/24161582/3208463\n",
  11263. " */\n",
  11264. "function simpleKeys (original) {\n",
  11265. " return Object.keys(original).reduce(function (obj, key) {\n",
  11266. " if (typeof original[key] !== 'object')\n",
  11267. " obj[key] = original[key]\n",
  11268. " return obj;\n",
  11269. " }, {});\n",
  11270. "}\n",
  11271. "\n",
  11272. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  11273. " var canvas_pos = mpl.findpos(event)\n",
  11274. "\n",
  11275. " if (name === 'button_press')\n",
  11276. " {\n",
  11277. " this.canvas.focus();\n",
  11278. " this.canvas_div.focus();\n",
  11279. " }\n",
  11280. "\n",
  11281. " var x = canvas_pos.x * mpl.ratio;\n",
  11282. " var y = canvas_pos.y * mpl.ratio;\n",
  11283. "\n",
  11284. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  11285. " step: event.step,\n",
  11286. " guiEvent: simpleKeys(event)});\n",
  11287. "\n",
  11288. " /* This prevents the web browser from automatically changing to\n",
  11289. " * the text insertion cursor when the button is pressed. We want\n",
  11290. " * to control all of the cursor setting manually through the\n",
  11291. " * 'cursor' event from matplotlib */\n",
  11292. " event.preventDefault();\n",
  11293. " return false;\n",
  11294. "}\n",
  11295. "\n",
  11296. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  11297. " // Handle any extra behaviour associated with a key event\n",
  11298. "}\n",
  11299. "\n",
  11300. "mpl.figure.prototype.key_event = function(event, name) {\n",
  11301. "\n",
  11302. " // Prevent repeat events\n",
  11303. " if (name == 'key_press')\n",
  11304. " {\n",
  11305. " if (event.which === this._key)\n",
  11306. " return;\n",
  11307. " else\n",
  11308. " this._key = event.which;\n",
  11309. " }\n",
  11310. " if (name == 'key_release')\n",
  11311. " this._key = null;\n",
  11312. "\n",
  11313. " var value = '';\n",
  11314. " if (event.ctrlKey && event.which != 17)\n",
  11315. " value += \"ctrl+\";\n",
  11316. " if (event.altKey && event.which != 18)\n",
  11317. " value += \"alt+\";\n",
  11318. " if (event.shiftKey && event.which != 16)\n",
  11319. " value += \"shift+\";\n",
  11320. "\n",
  11321. " value += 'k';\n",
  11322. " value += event.which.toString();\n",
  11323. "\n",
  11324. " this._key_event_extra(event, name);\n",
  11325. "\n",
  11326. " this.send_message(name, {key: value,\n",
  11327. " guiEvent: simpleKeys(event)});\n",
  11328. " return false;\n",
  11329. "}\n",
  11330. "\n",
  11331. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  11332. " if (name == 'download') {\n",
  11333. " this.handle_save(this, null);\n",
  11334. " } else {\n",
  11335. " this.send_message(\"toolbar_button\", {name: name});\n",
  11336. " }\n",
  11337. "};\n",
  11338. "\n",
  11339. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  11340. " this.message.textContent = tooltip;\n",
  11341. "};\n",
  11342. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  11343. "\n",
  11344. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  11345. "\n",
  11346. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  11347. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  11348. " // object with the appropriate methods. Currently this is a non binary\n",
  11349. " // socket, so there is still some room for performance tuning.\n",
  11350. " var ws = {};\n",
  11351. "\n",
  11352. " ws.close = function() {\n",
  11353. " comm.close()\n",
  11354. " };\n",
  11355. " ws.send = function(m) {\n",
  11356. " //console.log('sending', m);\n",
  11357. " comm.send(m);\n",
  11358. " };\n",
  11359. " // Register the callback with on_msg.\n",
  11360. " comm.on_msg(function(msg) {\n",
  11361. " //console.log('receiving', msg['content']['data'], msg);\n",
  11362. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  11363. " ws.onmessage(msg['content']['data'])\n",
  11364. " });\n",
  11365. " return ws;\n",
  11366. "}\n",
  11367. "\n",
  11368. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  11369. " // This is the function which gets called when the mpl process\n",
  11370. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  11371. "\n",
  11372. " var id = msg.content.data.id;\n",
  11373. " // Get hold of the div created by the display call when the Comm\n",
  11374. " // socket was opened in Python.\n",
  11375. " var element = $(\"#\" + id);\n",
  11376. " var ws_proxy = comm_websocket_adapter(comm)\n",
  11377. "\n",
  11378. " function ondownload(figure, format) {\n",
  11379. " window.open(figure.imageObj.src);\n",
  11380. " }\n",
  11381. "\n",
  11382. " var fig = new mpl.figure(id, ws_proxy,\n",
  11383. " ondownload,\n",
  11384. " element.get(0));\n",
  11385. "\n",
  11386. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  11387. " // web socket which is closed, not our websocket->open comm proxy.\n",
  11388. " ws_proxy.onopen();\n",
  11389. "\n",
  11390. " fig.parent_element = element.get(0);\n",
  11391. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  11392. " if (!fig.cell_info) {\n",
  11393. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  11394. " return;\n",
  11395. " }\n",
  11396. "\n",
  11397. " var output_index = fig.cell_info[2]\n",
  11398. " var cell = fig.cell_info[0];\n",
  11399. "\n",
  11400. "};\n",
  11401. "\n",
  11402. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  11403. " var width = fig.canvas.width/mpl.ratio\n",
  11404. " fig.root.unbind('remove')\n",
  11405. "\n",
  11406. " // Update the output cell to use the data from the current canvas.\n",
  11407. " fig.push_to_output();\n",
  11408. " var dataURL = fig.canvas.toDataURL();\n",
  11409. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  11410. " // the notebook keyboard shortcuts fail.\n",
  11411. " IPython.keyboard_manager.enable()\n",
  11412. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  11413. " fig.close_ws(fig, msg);\n",
  11414. "}\n",
  11415. "\n",
  11416. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  11417. " fig.send_message('closing', msg);\n",
  11418. " // fig.ws.close()\n",
  11419. "}\n",
  11420. "\n",
  11421. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  11422. " // Turn the data on the canvas into data in the output cell.\n",
  11423. " var width = this.canvas.width/mpl.ratio\n",
  11424. " var dataURL = this.canvas.toDataURL();\n",
  11425. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  11426. "}\n",
  11427. "\n",
  11428. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  11429. " // Tell IPython that the notebook contents must change.\n",
  11430. " IPython.notebook.set_dirty(true);\n",
  11431. " this.send_message(\"ack\", {});\n",
  11432. " var fig = this;\n",
  11433. " // Wait a second, then push the new image to the DOM so\n",
  11434. " // that it is saved nicely (might be nice to debounce this).\n",
  11435. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  11436. "}\n",
  11437. "\n",
  11438. "mpl.figure.prototype._init_toolbar = function() {\n",
  11439. " var fig = this;\n",
  11440. "\n",
  11441. " var nav_element = $('<div/>')\n",
  11442. " nav_element.attr('style', 'width: 100%');\n",
  11443. " this.root.append(nav_element);\n",
  11444. "\n",
  11445. " // Define a callback function for later on.\n",
  11446. " function toolbar_event(event) {\n",
  11447. " return fig.toolbar_button_onclick(event['data']);\n",
  11448. " }\n",
  11449. " function toolbar_mouse_event(event) {\n",
  11450. " return fig.toolbar_button_onmouseover(event['data']);\n",
  11451. " }\n",
  11452. "\n",
  11453. " for(var toolbar_ind in mpl.toolbar_items){\n",
  11454. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  11455. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  11456. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  11457. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  11458. "\n",
  11459. " if (!name) { continue; };\n",
  11460. "\n",
  11461. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  11462. " button.click(method_name, toolbar_event);\n",
  11463. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  11464. " nav_element.append(button);\n",
  11465. " }\n",
  11466. "\n",
  11467. " // Add the status bar.\n",
  11468. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  11469. " nav_element.append(status_bar);\n",
  11470. " this.message = status_bar[0];\n",
  11471. "\n",
  11472. " // Add the close button to the window.\n",
  11473. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  11474. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  11475. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  11476. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  11477. " buttongrp.append(button);\n",
  11478. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  11479. " titlebar.prepend(buttongrp);\n",
  11480. "}\n",
  11481. "\n",
  11482. "mpl.figure.prototype._root_extra_style = function(el){\n",
  11483. " var fig = this\n",
  11484. " el.on(\"remove\", function(){\n",
  11485. "\tfig.close_ws(fig, {});\n",
  11486. " });\n",
  11487. "}\n",
  11488. "\n",
  11489. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  11490. " // this is important to make the div 'focusable\n",
  11491. " el.attr('tabindex', 0)\n",
  11492. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  11493. " // off when our div gets focus\n",
  11494. "\n",
  11495. " // location in version 3\n",
  11496. " if (IPython.notebook.keyboard_manager) {\n",
  11497. " IPython.notebook.keyboard_manager.register_events(el);\n",
  11498. " }\n",
  11499. " else {\n",
  11500. " // location in version 2\n",
  11501. " IPython.keyboard_manager.register_events(el);\n",
  11502. " }\n",
  11503. "\n",
  11504. "}\n",
  11505. "\n",
  11506. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  11507. " var manager = IPython.notebook.keyboard_manager;\n",
  11508. " if (!manager)\n",
  11509. " manager = IPython.keyboard_manager;\n",
  11510. "\n",
  11511. " // Check for shift+enter\n",
  11512. " if (event.shiftKey && event.which == 13) {\n",
  11513. " this.canvas_div.blur();\n",
  11514. " event.shiftKey = false;\n",
  11515. " // Send a \"J\" for go to next cell\n",
  11516. " event.which = 74;\n",
  11517. " event.keyCode = 74;\n",
  11518. " manager.command_mode();\n",
  11519. " manager.handle_keydown(event);\n",
  11520. " }\n",
  11521. "}\n",
  11522. "\n",
  11523. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  11524. " fig.ondownload(fig, null);\n",
  11525. "}\n",
  11526. "\n",
  11527. "\n",
  11528. "mpl.find_output_cell = function(html_output) {\n",
  11529. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  11530. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  11531. " // IPython event is triggered only after the cells have been serialised, which for\n",
  11532. " // our purposes (turning an active figure into a static one), is too late.\n",
  11533. " var cells = IPython.notebook.get_cells();\n",
  11534. " var ncells = cells.length;\n",
  11535. " for (var i=0; i<ncells; i++) {\n",
  11536. " var cell = cells[i];\n",
  11537. " if (cell.cell_type === 'code'){\n",
  11538. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  11539. " var data = cell.output_area.outputs[j];\n",
  11540. " if (data.data) {\n",
  11541. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  11542. " data = data.data;\n",
  11543. " }\n",
  11544. " if (data['text/html'] == html_output) {\n",
  11545. " return [cell, data, j];\n",
  11546. " }\n",
  11547. " }\n",
  11548. " }\n",
  11549. " }\n",
  11550. "}\n",
  11551. "\n",
  11552. "// Register the function which deals with the matplotlib target/channel.\n",
  11553. "// The kernel may be null if the page has been refreshed.\n",
  11554. "if (IPython.notebook.kernel != null) {\n",
  11555. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  11556. "}\n"
  11557. ],
  11558. "text/plain": [
  11559. "<IPython.core.display.Javascript object>"
  11560. ]
  11561. },
  11562. "metadata": {},
  11563. "output_type": "display_data"
  11564. },
  11565. {
  11566. "data": {
  11567. "text/html": [
  11568. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  11569. ],
  11570. "text/plain": [
  11571. "<IPython.core.display.HTML object>"
  11572. ]
  11573. },
  11574. "metadata": {},
  11575. "output_type": "display_data"
  11576. },
  11577. {
  11578. "name": "stdout",
  11579. "output_type": "stream",
  11580. "text": [
  11581. "-0.21926743 4.912501\n",
  11582. "18525.77\n",
  11583. "(247, 212)\n",
  11584. "\n"
  11585. ]
  11586. },
  11587. {
  11588. "data": {
  11589. "application/javascript": [
  11590. "/* Put everything inside the global mpl namespace */\n",
  11591. "window.mpl = {};\n",
  11592. "\n",
  11593. "\n",
  11594. "mpl.get_websocket_type = function() {\n",
  11595. " if (typeof(WebSocket) !== 'undefined') {\n",
  11596. " return WebSocket;\n",
  11597. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  11598. " return MozWebSocket;\n",
  11599. " } else {\n",
  11600. " alert('Your browser does not have WebSocket support.' +\n",
  11601. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  11602. " 'Firefox 4 and 5 are also supported but you ' +\n",
  11603. " 'have to enable WebSockets in about:config.');\n",
  11604. " };\n",
  11605. "}\n",
  11606. "\n",
  11607. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  11608. " this.id = figure_id;\n",
  11609. "\n",
  11610. " this.ws = websocket;\n",
  11611. "\n",
  11612. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  11613. "\n",
  11614. " if (!this.supports_binary) {\n",
  11615. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  11616. " if (warnings) {\n",
  11617. " warnings.style.display = 'block';\n",
  11618. " warnings.textContent = (\n",
  11619. " \"This browser does not support binary websocket messages. \" +\n",
  11620. " \"Performance may be slow.\");\n",
  11621. " }\n",
  11622. " }\n",
  11623. "\n",
  11624. " this.imageObj = new Image();\n",
  11625. "\n",
  11626. " this.context = undefined;\n",
  11627. " this.message = undefined;\n",
  11628. " this.canvas = undefined;\n",
  11629. " this.rubberband_canvas = undefined;\n",
  11630. " this.rubberband_context = undefined;\n",
  11631. " this.format_dropdown = undefined;\n",
  11632. "\n",
  11633. " this.image_mode = 'full';\n",
  11634. "\n",
  11635. " this.root = $('<div/>');\n",
  11636. " this._root_extra_style(this.root)\n",
  11637. " this.root.attr('style', 'display: inline-block');\n",
  11638. "\n",
  11639. " $(parent_element).append(this.root);\n",
  11640. "\n",
  11641. " this._init_header(this);\n",
  11642. " this._init_canvas(this);\n",
  11643. " this._init_toolbar(this);\n",
  11644. "\n",
  11645. " var fig = this;\n",
  11646. "\n",
  11647. " this.waiting = false;\n",
  11648. "\n",
  11649. " this.ws.onopen = function () {\n",
  11650. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  11651. " fig.send_message(\"send_image_mode\", {});\n",
  11652. " if (mpl.ratio != 1) {\n",
  11653. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  11654. " }\n",
  11655. " fig.send_message(\"refresh\", {});\n",
  11656. " }\n",
  11657. "\n",
  11658. " this.imageObj.onload = function() {\n",
  11659. " if (fig.image_mode == 'full') {\n",
  11660. " // Full images could contain transparency (where diff images\n",
  11661. " // almost always do), so we need to clear the canvas so that\n",
  11662. " // there is no ghosting.\n",
  11663. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  11664. " }\n",
  11665. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  11666. " };\n",
  11667. "\n",
  11668. " this.imageObj.onunload = function() {\n",
  11669. " fig.ws.close();\n",
  11670. " }\n",
  11671. "\n",
  11672. " this.ws.onmessage = this._make_on_message_function(this);\n",
  11673. "\n",
  11674. " this.ondownload = ondownload;\n",
  11675. "}\n",
  11676. "\n",
  11677. "mpl.figure.prototype._init_header = function() {\n",
  11678. " var titlebar = $(\n",
  11679. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  11680. " 'ui-helper-clearfix\"/>');\n",
  11681. " var titletext = $(\n",
  11682. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  11683. " 'text-align: center; padding: 3px;\"/>');\n",
  11684. " titlebar.append(titletext)\n",
  11685. " this.root.append(titlebar);\n",
  11686. " this.header = titletext[0];\n",
  11687. "}\n",
  11688. "\n",
  11689. "\n",
  11690. "\n",
  11691. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  11692. "\n",
  11693. "}\n",
  11694. "\n",
  11695. "\n",
  11696. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  11697. "\n",
  11698. "}\n",
  11699. "\n",
  11700. "mpl.figure.prototype._init_canvas = function() {\n",
  11701. " var fig = this;\n",
  11702. "\n",
  11703. " var canvas_div = $('<div/>');\n",
  11704. "\n",
  11705. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  11706. "\n",
  11707. " function canvas_keyboard_event(event) {\n",
  11708. " return fig.key_event(event, event['data']);\n",
  11709. " }\n",
  11710. "\n",
  11711. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  11712. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  11713. " this.canvas_div = canvas_div\n",
  11714. " this._canvas_extra_style(canvas_div)\n",
  11715. " this.root.append(canvas_div);\n",
  11716. "\n",
  11717. " var canvas = $('<canvas/>');\n",
  11718. " canvas.addClass('mpl-canvas');\n",
  11719. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  11720. "\n",
  11721. " this.canvas = canvas[0];\n",
  11722. " this.context = canvas[0].getContext(\"2d\");\n",
  11723. "\n",
  11724. " var backingStore = this.context.backingStorePixelRatio ||\n",
  11725. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  11726. "\tthis.context.mozBackingStorePixelRatio ||\n",
  11727. "\tthis.context.msBackingStorePixelRatio ||\n",
  11728. "\tthis.context.oBackingStorePixelRatio ||\n",
  11729. "\tthis.context.backingStorePixelRatio || 1;\n",
  11730. "\n",
  11731. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  11732. "\n",
  11733. " var rubberband = $('<canvas/>');\n",
  11734. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  11735. "\n",
  11736. " var pass_mouse_events = true;\n",
  11737. "\n",
  11738. " canvas_div.resizable({\n",
  11739. " start: function(event, ui) {\n",
  11740. " pass_mouse_events = false;\n",
  11741. " },\n",
  11742. " resize: function(event, ui) {\n",
  11743. " fig.request_resize(ui.size.width, ui.size.height);\n",
  11744. " },\n",
  11745. " stop: function(event, ui) {\n",
  11746. " pass_mouse_events = true;\n",
  11747. " fig.request_resize(ui.size.width, ui.size.height);\n",
  11748. " },\n",
  11749. " });\n",
  11750. "\n",
  11751. " function mouse_event_fn(event) {\n",
  11752. " if (pass_mouse_events)\n",
  11753. " return fig.mouse_event(event, event['data']);\n",
  11754. " }\n",
  11755. "\n",
  11756. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  11757. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  11758. " // Throttle sequential mouse events to 1 every 20ms.\n",
  11759. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  11760. "\n",
  11761. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  11762. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  11763. "\n",
  11764. " canvas_div.on(\"wheel\", function (event) {\n",
  11765. " event = event.originalEvent;\n",
  11766. " event['data'] = 'scroll'\n",
  11767. " if (event.deltaY < 0) {\n",
  11768. " event.step = 1;\n",
  11769. " } else {\n",
  11770. " event.step = -1;\n",
  11771. " }\n",
  11772. " mouse_event_fn(event);\n",
  11773. " });\n",
  11774. "\n",
  11775. " canvas_div.append(canvas);\n",
  11776. " canvas_div.append(rubberband);\n",
  11777. "\n",
  11778. " this.rubberband = rubberband;\n",
  11779. " this.rubberband_canvas = rubberband[0];\n",
  11780. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  11781. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  11782. "\n",
  11783. " this._resize_canvas = function(width, height) {\n",
  11784. " // Keep the size of the canvas, canvas container, and rubber band\n",
  11785. " // canvas in synch.\n",
  11786. " canvas_div.css('width', width)\n",
  11787. " canvas_div.css('height', height)\n",
  11788. "\n",
  11789. " canvas.attr('width', width * mpl.ratio);\n",
  11790. " canvas.attr('height', height * mpl.ratio);\n",
  11791. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  11792. "\n",
  11793. " rubberband.attr('width', width);\n",
  11794. " rubberband.attr('height', height);\n",
  11795. " }\n",
  11796. "\n",
  11797. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  11798. " // upon first draw.\n",
  11799. " this._resize_canvas(600, 600);\n",
  11800. "\n",
  11801. " // Disable right mouse context menu.\n",
  11802. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  11803. " return false;\n",
  11804. " });\n",
  11805. "\n",
  11806. " function set_focus () {\n",
  11807. " canvas.focus();\n",
  11808. " canvas_div.focus();\n",
  11809. " }\n",
  11810. "\n",
  11811. " window.setTimeout(set_focus, 100);\n",
  11812. "}\n",
  11813. "\n",
  11814. "mpl.figure.prototype._init_toolbar = function() {\n",
  11815. " var fig = this;\n",
  11816. "\n",
  11817. " var nav_element = $('<div/>')\n",
  11818. " nav_element.attr('style', 'width: 100%');\n",
  11819. " this.root.append(nav_element);\n",
  11820. "\n",
  11821. " // Define a callback function for later on.\n",
  11822. " function toolbar_event(event) {\n",
  11823. " return fig.toolbar_button_onclick(event['data']);\n",
  11824. " }\n",
  11825. " function toolbar_mouse_event(event) {\n",
  11826. " return fig.toolbar_button_onmouseover(event['data']);\n",
  11827. " }\n",
  11828. "\n",
  11829. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  11830. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  11831. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  11832. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  11833. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  11834. "\n",
  11835. " if (!name) {\n",
  11836. " // put a spacer in here.\n",
  11837. " continue;\n",
  11838. " }\n",
  11839. " var button = $('<button/>');\n",
  11840. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  11841. " 'ui-button-icon-only');\n",
  11842. " button.attr('role', 'button');\n",
  11843. " button.attr('aria-disabled', 'false');\n",
  11844. " button.click(method_name, toolbar_event);\n",
  11845. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  11846. "\n",
  11847. " var icon_img = $('<span/>');\n",
  11848. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  11849. " icon_img.addClass(image);\n",
  11850. " icon_img.addClass('ui-corner-all');\n",
  11851. "\n",
  11852. " var tooltip_span = $('<span/>');\n",
  11853. " tooltip_span.addClass('ui-button-text');\n",
  11854. " tooltip_span.html(tooltip);\n",
  11855. "\n",
  11856. " button.append(icon_img);\n",
  11857. " button.append(tooltip_span);\n",
  11858. "\n",
  11859. " nav_element.append(button);\n",
  11860. " }\n",
  11861. "\n",
  11862. " var fmt_picker_span = $('<span/>');\n",
  11863. "\n",
  11864. " var fmt_picker = $('<select/>');\n",
  11865. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  11866. " fmt_picker_span.append(fmt_picker);\n",
  11867. " nav_element.append(fmt_picker_span);\n",
  11868. " this.format_dropdown = fmt_picker[0];\n",
  11869. "\n",
  11870. " for (var ind in mpl.extensions) {\n",
  11871. " var fmt = mpl.extensions[ind];\n",
  11872. " var option = $(\n",
  11873. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  11874. " fmt_picker.append(option)\n",
  11875. " }\n",
  11876. "\n",
  11877. " // Add hover states to the ui-buttons\n",
  11878. " $( \".ui-button\" ).hover(\n",
  11879. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  11880. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  11881. " );\n",
  11882. "\n",
  11883. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  11884. " nav_element.append(status_bar);\n",
  11885. " this.message = status_bar[0];\n",
  11886. "}\n",
  11887. "\n",
  11888. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  11889. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  11890. " // which will in turn request a refresh of the image.\n",
  11891. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  11892. "}\n",
  11893. "\n",
  11894. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  11895. " properties['type'] = type;\n",
  11896. " properties['figure_id'] = this.id;\n",
  11897. " this.ws.send(JSON.stringify(properties));\n",
  11898. "}\n",
  11899. "\n",
  11900. "mpl.figure.prototype.send_draw_message = function() {\n",
  11901. " if (!this.waiting) {\n",
  11902. " this.waiting = true;\n",
  11903. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  11904. " }\n",
  11905. "}\n",
  11906. "\n",
  11907. "\n",
  11908. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  11909. " var format_dropdown = fig.format_dropdown;\n",
  11910. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  11911. " fig.ondownload(fig, format);\n",
  11912. "}\n",
  11913. "\n",
  11914. "\n",
  11915. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  11916. " var size = msg['size'];\n",
  11917. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  11918. " fig._resize_canvas(size[0], size[1]);\n",
  11919. " fig.send_message(\"refresh\", {});\n",
  11920. " };\n",
  11921. "}\n",
  11922. "\n",
  11923. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  11924. " var x0 = msg['x0'] / mpl.ratio;\n",
  11925. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  11926. " var x1 = msg['x1'] / mpl.ratio;\n",
  11927. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  11928. " x0 = Math.floor(x0) + 0.5;\n",
  11929. " y0 = Math.floor(y0) + 0.5;\n",
  11930. " x1 = Math.floor(x1) + 0.5;\n",
  11931. " y1 = Math.floor(y1) + 0.5;\n",
  11932. " var min_x = Math.min(x0, x1);\n",
  11933. " var min_y = Math.min(y0, y1);\n",
  11934. " var width = Math.abs(x1 - x0);\n",
  11935. " var height = Math.abs(y1 - y0);\n",
  11936. "\n",
  11937. " fig.rubberband_context.clearRect(\n",
  11938. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  11939. "\n",
  11940. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  11941. "}\n",
  11942. "\n",
  11943. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  11944. " // Updates the figure title.\n",
  11945. " fig.header.textContent = msg['label'];\n",
  11946. "}\n",
  11947. "\n",
  11948. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  11949. " var cursor = msg['cursor'];\n",
  11950. " switch(cursor)\n",
  11951. " {\n",
  11952. " case 0:\n",
  11953. " cursor = 'pointer';\n",
  11954. " break;\n",
  11955. " case 1:\n",
  11956. " cursor = 'default';\n",
  11957. " break;\n",
  11958. " case 2:\n",
  11959. " cursor = 'crosshair';\n",
  11960. " break;\n",
  11961. " case 3:\n",
  11962. " cursor = 'move';\n",
  11963. " break;\n",
  11964. " }\n",
  11965. " fig.rubberband_canvas.style.cursor = cursor;\n",
  11966. "}\n",
  11967. "\n",
  11968. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  11969. " fig.message.textContent = msg['message'];\n",
  11970. "}\n",
  11971. "\n",
  11972. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  11973. " // Request the server to send over a new figure.\n",
  11974. " fig.send_draw_message();\n",
  11975. "}\n",
  11976. "\n",
  11977. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  11978. " fig.image_mode = msg['mode'];\n",
  11979. "}\n",
  11980. "\n",
  11981. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  11982. " // Called whenever the canvas gets updated.\n",
  11983. " this.send_message(\"ack\", {});\n",
  11984. "}\n",
  11985. "\n",
  11986. "// A function to construct a web socket function for onmessage handling.\n",
  11987. "// Called in the figure constructor.\n",
  11988. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  11989. " return function socket_on_message(evt) {\n",
  11990. " if (evt.data instanceof Blob) {\n",
  11991. " /* FIXME: We get \"Resource interpreted as Image but\n",
  11992. " * transferred with MIME type text/plain:\" errors on\n",
  11993. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  11994. " * to be part of the websocket stream */\n",
  11995. " evt.data.type = \"image/png\";\n",
  11996. "\n",
  11997. " /* Free the memory for the previous frames */\n",
  11998. " if (fig.imageObj.src) {\n",
  11999. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  12000. " fig.imageObj.src);\n",
  12001. " }\n",
  12002. "\n",
  12003. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  12004. " evt.data);\n",
  12005. " fig.updated_canvas_event();\n",
  12006. " fig.waiting = false;\n",
  12007. " return;\n",
  12008. " }\n",
  12009. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  12010. " fig.imageObj.src = evt.data;\n",
  12011. " fig.updated_canvas_event();\n",
  12012. " fig.waiting = false;\n",
  12013. " return;\n",
  12014. " }\n",
  12015. "\n",
  12016. " var msg = JSON.parse(evt.data);\n",
  12017. " var msg_type = msg['type'];\n",
  12018. "\n",
  12019. " // Call the \"handle_{type}\" callback, which takes\n",
  12020. " // the figure and JSON message as its only arguments.\n",
  12021. " try {\n",
  12022. " var callback = fig[\"handle_\" + msg_type];\n",
  12023. " } catch (e) {\n",
  12024. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  12025. " return;\n",
  12026. " }\n",
  12027. "\n",
  12028. " if (callback) {\n",
  12029. " try {\n",
  12030. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  12031. " callback(fig, msg);\n",
  12032. " } catch (e) {\n",
  12033. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  12034. " }\n",
  12035. " }\n",
  12036. " };\n",
  12037. "}\n",
  12038. "\n",
  12039. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  12040. "mpl.findpos = function(e) {\n",
  12041. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  12042. " var targ;\n",
  12043. " if (!e)\n",
  12044. " e = window.event;\n",
  12045. " if (e.target)\n",
  12046. " targ = e.target;\n",
  12047. " else if (e.srcElement)\n",
  12048. " targ = e.srcElement;\n",
  12049. " if (targ.nodeType == 3) // defeat Safari bug\n",
  12050. " targ = targ.parentNode;\n",
  12051. "\n",
  12052. " // jQuery normalizes the pageX and pageY\n",
  12053. " // pageX,Y are the mouse positions relative to the document\n",
  12054. " // offset() returns the position of the element relative to the document\n",
  12055. " var x = e.pageX - $(targ).offset().left;\n",
  12056. " var y = e.pageY - $(targ).offset().top;\n",
  12057. "\n",
  12058. " return {\"x\": x, \"y\": y};\n",
  12059. "};\n",
  12060. "\n",
  12061. "/*\n",
  12062. " * return a copy of an object with only non-object keys\n",
  12063. " * we need this to avoid circular references\n",
  12064. " * http://stackoverflow.com/a/24161582/3208463\n",
  12065. " */\n",
  12066. "function simpleKeys (original) {\n",
  12067. " return Object.keys(original).reduce(function (obj, key) {\n",
  12068. " if (typeof original[key] !== 'object')\n",
  12069. " obj[key] = original[key]\n",
  12070. " return obj;\n",
  12071. " }, {});\n",
  12072. "}\n",
  12073. "\n",
  12074. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  12075. " var canvas_pos = mpl.findpos(event)\n",
  12076. "\n",
  12077. " if (name === 'button_press')\n",
  12078. " {\n",
  12079. " this.canvas.focus();\n",
  12080. " this.canvas_div.focus();\n",
  12081. " }\n",
  12082. "\n",
  12083. " var x = canvas_pos.x * mpl.ratio;\n",
  12084. " var y = canvas_pos.y * mpl.ratio;\n",
  12085. "\n",
  12086. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  12087. " step: event.step,\n",
  12088. " guiEvent: simpleKeys(event)});\n",
  12089. "\n",
  12090. " /* This prevents the web browser from automatically changing to\n",
  12091. " * the text insertion cursor when the button is pressed. We want\n",
  12092. " * to control all of the cursor setting manually through the\n",
  12093. " * 'cursor' event from matplotlib */\n",
  12094. " event.preventDefault();\n",
  12095. " return false;\n",
  12096. "}\n",
  12097. "\n",
  12098. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  12099. " // Handle any extra behaviour associated with a key event\n",
  12100. "}\n",
  12101. "\n",
  12102. "mpl.figure.prototype.key_event = function(event, name) {\n",
  12103. "\n",
  12104. " // Prevent repeat events\n",
  12105. " if (name == 'key_press')\n",
  12106. " {\n",
  12107. " if (event.which === this._key)\n",
  12108. " return;\n",
  12109. " else\n",
  12110. " this._key = event.which;\n",
  12111. " }\n",
  12112. " if (name == 'key_release')\n",
  12113. " this._key = null;\n",
  12114. "\n",
  12115. " var value = '';\n",
  12116. " if (event.ctrlKey && event.which != 17)\n",
  12117. " value += \"ctrl+\";\n",
  12118. " if (event.altKey && event.which != 18)\n",
  12119. " value += \"alt+\";\n",
  12120. " if (event.shiftKey && event.which != 16)\n",
  12121. " value += \"shift+\";\n",
  12122. "\n",
  12123. " value += 'k';\n",
  12124. " value += event.which.toString();\n",
  12125. "\n",
  12126. " this._key_event_extra(event, name);\n",
  12127. "\n",
  12128. " this.send_message(name, {key: value,\n",
  12129. " guiEvent: simpleKeys(event)});\n",
  12130. " return false;\n",
  12131. "}\n",
  12132. "\n",
  12133. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  12134. " if (name == 'download') {\n",
  12135. " this.handle_save(this, null);\n",
  12136. " } else {\n",
  12137. " this.send_message(\"toolbar_button\", {name: name});\n",
  12138. " }\n",
  12139. "};\n",
  12140. "\n",
  12141. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  12142. " this.message.textContent = tooltip;\n",
  12143. "};\n",
  12144. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  12145. "\n",
  12146. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  12147. "\n",
  12148. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  12149. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  12150. " // object with the appropriate methods. Currently this is a non binary\n",
  12151. " // socket, so there is still some room for performance tuning.\n",
  12152. " var ws = {};\n",
  12153. "\n",
  12154. " ws.close = function() {\n",
  12155. " comm.close()\n",
  12156. " };\n",
  12157. " ws.send = function(m) {\n",
  12158. " //console.log('sending', m);\n",
  12159. " comm.send(m);\n",
  12160. " };\n",
  12161. " // Register the callback with on_msg.\n",
  12162. " comm.on_msg(function(msg) {\n",
  12163. " //console.log('receiving', msg['content']['data'], msg);\n",
  12164. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  12165. " ws.onmessage(msg['content']['data'])\n",
  12166. " });\n",
  12167. " return ws;\n",
  12168. "}\n",
  12169. "\n",
  12170. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  12171. " // This is the function which gets called when the mpl process\n",
  12172. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  12173. "\n",
  12174. " var id = msg.content.data.id;\n",
  12175. " // Get hold of the div created by the display call when the Comm\n",
  12176. " // socket was opened in Python.\n",
  12177. " var element = $(\"#\" + id);\n",
  12178. " var ws_proxy = comm_websocket_adapter(comm)\n",
  12179. "\n",
  12180. " function ondownload(figure, format) {\n",
  12181. " window.open(figure.imageObj.src);\n",
  12182. " }\n",
  12183. "\n",
  12184. " var fig = new mpl.figure(id, ws_proxy,\n",
  12185. " ondownload,\n",
  12186. " element.get(0));\n",
  12187. "\n",
  12188. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  12189. " // web socket which is closed, not our websocket->open comm proxy.\n",
  12190. " ws_proxy.onopen();\n",
  12191. "\n",
  12192. " fig.parent_element = element.get(0);\n",
  12193. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  12194. " if (!fig.cell_info) {\n",
  12195. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  12196. " return;\n",
  12197. " }\n",
  12198. "\n",
  12199. " var output_index = fig.cell_info[2]\n",
  12200. " var cell = fig.cell_info[0];\n",
  12201. "\n",
  12202. "};\n",
  12203. "\n",
  12204. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  12205. " var width = fig.canvas.width/mpl.ratio\n",
  12206. " fig.root.unbind('remove')\n",
  12207. "\n",
  12208. " // Update the output cell to use the data from the current canvas.\n",
  12209. " fig.push_to_output();\n",
  12210. " var dataURL = fig.canvas.toDataURL();\n",
  12211. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  12212. " // the notebook keyboard shortcuts fail.\n",
  12213. " IPython.keyboard_manager.enable()\n",
  12214. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  12215. " fig.close_ws(fig, msg);\n",
  12216. "}\n",
  12217. "\n",
  12218. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  12219. " fig.send_message('closing', msg);\n",
  12220. " // fig.ws.close()\n",
  12221. "}\n",
  12222. "\n",
  12223. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  12224. " // Turn the data on the canvas into data in the output cell.\n",
  12225. " var width = this.canvas.width/mpl.ratio\n",
  12226. " var dataURL = this.canvas.toDataURL();\n",
  12227. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  12228. "}\n",
  12229. "\n",
  12230. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  12231. " // Tell IPython that the notebook contents must change.\n",
  12232. " IPython.notebook.set_dirty(true);\n",
  12233. " this.send_message(\"ack\", {});\n",
  12234. " var fig = this;\n",
  12235. " // Wait a second, then push the new image to the DOM so\n",
  12236. " // that it is saved nicely (might be nice to debounce this).\n",
  12237. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  12238. "}\n",
  12239. "\n",
  12240. "mpl.figure.prototype._init_toolbar = function() {\n",
  12241. " var fig = this;\n",
  12242. "\n",
  12243. " var nav_element = $('<div/>')\n",
  12244. " nav_element.attr('style', 'width: 100%');\n",
  12245. " this.root.append(nav_element);\n",
  12246. "\n",
  12247. " // Define a callback function for later on.\n",
  12248. " function toolbar_event(event) {\n",
  12249. " return fig.toolbar_button_onclick(event['data']);\n",
  12250. " }\n",
  12251. " function toolbar_mouse_event(event) {\n",
  12252. " return fig.toolbar_button_onmouseover(event['data']);\n",
  12253. " }\n",
  12254. "\n",
  12255. " for(var toolbar_ind in mpl.toolbar_items){\n",
  12256. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  12257. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  12258. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  12259. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  12260. "\n",
  12261. " if (!name) { continue; };\n",
  12262. "\n",
  12263. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  12264. " button.click(method_name, toolbar_event);\n",
  12265. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  12266. " nav_element.append(button);\n",
  12267. " }\n",
  12268. "\n",
  12269. " // Add the status bar.\n",
  12270. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  12271. " nav_element.append(status_bar);\n",
  12272. " this.message = status_bar[0];\n",
  12273. "\n",
  12274. " // Add the close button to the window.\n",
  12275. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  12276. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  12277. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  12278. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  12279. " buttongrp.append(button);\n",
  12280. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  12281. " titlebar.prepend(buttongrp);\n",
  12282. "}\n",
  12283. "\n",
  12284. "mpl.figure.prototype._root_extra_style = function(el){\n",
  12285. " var fig = this\n",
  12286. " el.on(\"remove\", function(){\n",
  12287. "\tfig.close_ws(fig, {});\n",
  12288. " });\n",
  12289. "}\n",
  12290. "\n",
  12291. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  12292. " // this is important to make the div 'focusable\n",
  12293. " el.attr('tabindex', 0)\n",
  12294. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  12295. " // off when our div gets focus\n",
  12296. "\n",
  12297. " // location in version 3\n",
  12298. " if (IPython.notebook.keyboard_manager) {\n",
  12299. " IPython.notebook.keyboard_manager.register_events(el);\n",
  12300. " }\n",
  12301. " else {\n",
  12302. " // location in version 2\n",
  12303. " IPython.keyboard_manager.register_events(el);\n",
  12304. " }\n",
  12305. "\n",
  12306. "}\n",
  12307. "\n",
  12308. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  12309. " var manager = IPython.notebook.keyboard_manager;\n",
  12310. " if (!manager)\n",
  12311. " manager = IPython.keyboard_manager;\n",
  12312. "\n",
  12313. " // Check for shift+enter\n",
  12314. " if (event.shiftKey && event.which == 13) {\n",
  12315. " this.canvas_div.blur();\n",
  12316. " event.shiftKey = false;\n",
  12317. " // Send a \"J\" for go to next cell\n",
  12318. " event.which = 74;\n",
  12319. " event.keyCode = 74;\n",
  12320. " manager.command_mode();\n",
  12321. " manager.handle_keydown(event);\n",
  12322. " }\n",
  12323. "}\n",
  12324. "\n",
  12325. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  12326. " fig.ondownload(fig, null);\n",
  12327. "}\n",
  12328. "\n",
  12329. "\n",
  12330. "mpl.find_output_cell = function(html_output) {\n",
  12331. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  12332. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  12333. " // IPython event is triggered only after the cells have been serialised, which for\n",
  12334. " // our purposes (turning an active figure into a static one), is too late.\n",
  12335. " var cells = IPython.notebook.get_cells();\n",
  12336. " var ncells = cells.length;\n",
  12337. " for (var i=0; i<ncells; i++) {\n",
  12338. " var cell = cells[i];\n",
  12339. " if (cell.cell_type === 'code'){\n",
  12340. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  12341. " var data = cell.output_area.outputs[j];\n",
  12342. " if (data.data) {\n",
  12343. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  12344. " data = data.data;\n",
  12345. " }\n",
  12346. " if (data['text/html'] == html_output) {\n",
  12347. " return [cell, data, j];\n",
  12348. " }\n",
  12349. " }\n",
  12350. " }\n",
  12351. " }\n",
  12352. "}\n",
  12353. "\n",
  12354. "// Register the function which deals with the matplotlib target/channel.\n",
  12355. "// The kernel may be null if the page has been refreshed.\n",
  12356. "if (IPython.notebook.kernel != null) {\n",
  12357. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  12358. "}\n"
  12359. ],
  12360. "text/plain": [
  12361. "<IPython.core.display.Javascript object>"
  12362. ]
  12363. },
  12364. "metadata": {},
  12365. "output_type": "display_data"
  12366. },
  12367. {
  12368. "data": {
  12369. "text/html": [
  12370. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  12371. ],
  12372. "text/plain": [
  12373. "<IPython.core.display.HTML object>"
  12374. ]
  12375. },
  12376. "metadata": {},
  12377. "output_type": "display_data"
  12378. },
  12379. {
  12380. "name": "stdout",
  12381. "output_type": "stream",
  12382. "text": [
  12383. "0.0 1.0\n",
  12384. "785.0\n",
  12385. "(351, 314)\n",
  12386. "\n"
  12387. ]
  12388. },
  12389. {
  12390. "data": {
  12391. "application/javascript": [
  12392. "/* Put everything inside the global mpl namespace */\n",
  12393. "window.mpl = {};\n",
  12394. "\n",
  12395. "\n",
  12396. "mpl.get_websocket_type = function() {\n",
  12397. " if (typeof(WebSocket) !== 'undefined') {\n",
  12398. " return WebSocket;\n",
  12399. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  12400. " return MozWebSocket;\n",
  12401. " } else {\n",
  12402. " alert('Your browser does not have WebSocket support.' +\n",
  12403. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  12404. " 'Firefox 4 and 5 are also supported but you ' +\n",
  12405. " 'have to enable WebSockets in about:config.');\n",
  12406. " };\n",
  12407. "}\n",
  12408. "\n",
  12409. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  12410. " this.id = figure_id;\n",
  12411. "\n",
  12412. " this.ws = websocket;\n",
  12413. "\n",
  12414. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  12415. "\n",
  12416. " if (!this.supports_binary) {\n",
  12417. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  12418. " if (warnings) {\n",
  12419. " warnings.style.display = 'block';\n",
  12420. " warnings.textContent = (\n",
  12421. " \"This browser does not support binary websocket messages. \" +\n",
  12422. " \"Performance may be slow.\");\n",
  12423. " }\n",
  12424. " }\n",
  12425. "\n",
  12426. " this.imageObj = new Image();\n",
  12427. "\n",
  12428. " this.context = undefined;\n",
  12429. " this.message = undefined;\n",
  12430. " this.canvas = undefined;\n",
  12431. " this.rubberband_canvas = undefined;\n",
  12432. " this.rubberband_context = undefined;\n",
  12433. " this.format_dropdown = undefined;\n",
  12434. "\n",
  12435. " this.image_mode = 'full';\n",
  12436. "\n",
  12437. " this.root = $('<div/>');\n",
  12438. " this._root_extra_style(this.root)\n",
  12439. " this.root.attr('style', 'display: inline-block');\n",
  12440. "\n",
  12441. " $(parent_element).append(this.root);\n",
  12442. "\n",
  12443. " this._init_header(this);\n",
  12444. " this._init_canvas(this);\n",
  12445. " this._init_toolbar(this);\n",
  12446. "\n",
  12447. " var fig = this;\n",
  12448. "\n",
  12449. " this.waiting = false;\n",
  12450. "\n",
  12451. " this.ws.onopen = function () {\n",
  12452. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  12453. " fig.send_message(\"send_image_mode\", {});\n",
  12454. " if (mpl.ratio != 1) {\n",
  12455. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  12456. " }\n",
  12457. " fig.send_message(\"refresh\", {});\n",
  12458. " }\n",
  12459. "\n",
  12460. " this.imageObj.onload = function() {\n",
  12461. " if (fig.image_mode == 'full') {\n",
  12462. " // Full images could contain transparency (where diff images\n",
  12463. " // almost always do), so we need to clear the canvas so that\n",
  12464. " // there is no ghosting.\n",
  12465. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  12466. " }\n",
  12467. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  12468. " };\n",
  12469. "\n",
  12470. " this.imageObj.onunload = function() {\n",
  12471. " fig.ws.close();\n",
  12472. " }\n",
  12473. "\n",
  12474. " this.ws.onmessage = this._make_on_message_function(this);\n",
  12475. "\n",
  12476. " this.ondownload = ondownload;\n",
  12477. "}\n",
  12478. "\n",
  12479. "mpl.figure.prototype._init_header = function() {\n",
  12480. " var titlebar = $(\n",
  12481. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  12482. " 'ui-helper-clearfix\"/>');\n",
  12483. " var titletext = $(\n",
  12484. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  12485. " 'text-align: center; padding: 3px;\"/>');\n",
  12486. " titlebar.append(titletext)\n",
  12487. " this.root.append(titlebar);\n",
  12488. " this.header = titletext[0];\n",
  12489. "}\n",
  12490. "\n",
  12491. "\n",
  12492. "\n",
  12493. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  12494. "\n",
  12495. "}\n",
  12496. "\n",
  12497. "\n",
  12498. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  12499. "\n",
  12500. "}\n",
  12501. "\n",
  12502. "mpl.figure.prototype._init_canvas = function() {\n",
  12503. " var fig = this;\n",
  12504. "\n",
  12505. " var canvas_div = $('<div/>');\n",
  12506. "\n",
  12507. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  12508. "\n",
  12509. " function canvas_keyboard_event(event) {\n",
  12510. " return fig.key_event(event, event['data']);\n",
  12511. " }\n",
  12512. "\n",
  12513. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  12514. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  12515. " this.canvas_div = canvas_div\n",
  12516. " this._canvas_extra_style(canvas_div)\n",
  12517. " this.root.append(canvas_div);\n",
  12518. "\n",
  12519. " var canvas = $('<canvas/>');\n",
  12520. " canvas.addClass('mpl-canvas');\n",
  12521. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  12522. "\n",
  12523. " this.canvas = canvas[0];\n",
  12524. " this.context = canvas[0].getContext(\"2d\");\n",
  12525. "\n",
  12526. " var backingStore = this.context.backingStorePixelRatio ||\n",
  12527. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  12528. "\tthis.context.mozBackingStorePixelRatio ||\n",
  12529. "\tthis.context.msBackingStorePixelRatio ||\n",
  12530. "\tthis.context.oBackingStorePixelRatio ||\n",
  12531. "\tthis.context.backingStorePixelRatio || 1;\n",
  12532. "\n",
  12533. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  12534. "\n",
  12535. " var rubberband = $('<canvas/>');\n",
  12536. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  12537. "\n",
  12538. " var pass_mouse_events = true;\n",
  12539. "\n",
  12540. " canvas_div.resizable({\n",
  12541. " start: function(event, ui) {\n",
  12542. " pass_mouse_events = false;\n",
  12543. " },\n",
  12544. " resize: function(event, ui) {\n",
  12545. " fig.request_resize(ui.size.width, ui.size.height);\n",
  12546. " },\n",
  12547. " stop: function(event, ui) {\n",
  12548. " pass_mouse_events = true;\n",
  12549. " fig.request_resize(ui.size.width, ui.size.height);\n",
  12550. " },\n",
  12551. " });\n",
  12552. "\n",
  12553. " function mouse_event_fn(event) {\n",
  12554. " if (pass_mouse_events)\n",
  12555. " return fig.mouse_event(event, event['data']);\n",
  12556. " }\n",
  12557. "\n",
  12558. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  12559. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  12560. " // Throttle sequential mouse events to 1 every 20ms.\n",
  12561. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  12562. "\n",
  12563. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  12564. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  12565. "\n",
  12566. " canvas_div.on(\"wheel\", function (event) {\n",
  12567. " event = event.originalEvent;\n",
  12568. " event['data'] = 'scroll'\n",
  12569. " if (event.deltaY < 0) {\n",
  12570. " event.step = 1;\n",
  12571. " } else {\n",
  12572. " event.step = -1;\n",
  12573. " }\n",
  12574. " mouse_event_fn(event);\n",
  12575. " });\n",
  12576. "\n",
  12577. " canvas_div.append(canvas);\n",
  12578. " canvas_div.append(rubberband);\n",
  12579. "\n",
  12580. " this.rubberband = rubberband;\n",
  12581. " this.rubberband_canvas = rubberband[0];\n",
  12582. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  12583. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  12584. "\n",
  12585. " this._resize_canvas = function(width, height) {\n",
  12586. " // Keep the size of the canvas, canvas container, and rubber band\n",
  12587. " // canvas in synch.\n",
  12588. " canvas_div.css('width', width)\n",
  12589. " canvas_div.css('height', height)\n",
  12590. "\n",
  12591. " canvas.attr('width', width * mpl.ratio);\n",
  12592. " canvas.attr('height', height * mpl.ratio);\n",
  12593. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  12594. "\n",
  12595. " rubberband.attr('width', width);\n",
  12596. " rubberband.attr('height', height);\n",
  12597. " }\n",
  12598. "\n",
  12599. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  12600. " // upon first draw.\n",
  12601. " this._resize_canvas(600, 600);\n",
  12602. "\n",
  12603. " // Disable right mouse context menu.\n",
  12604. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  12605. " return false;\n",
  12606. " });\n",
  12607. "\n",
  12608. " function set_focus () {\n",
  12609. " canvas.focus();\n",
  12610. " canvas_div.focus();\n",
  12611. " }\n",
  12612. "\n",
  12613. " window.setTimeout(set_focus, 100);\n",
  12614. "}\n",
  12615. "\n",
  12616. "mpl.figure.prototype._init_toolbar = function() {\n",
  12617. " var fig = this;\n",
  12618. "\n",
  12619. " var nav_element = $('<div/>')\n",
  12620. " nav_element.attr('style', 'width: 100%');\n",
  12621. " this.root.append(nav_element);\n",
  12622. "\n",
  12623. " // Define a callback function for later on.\n",
  12624. " function toolbar_event(event) {\n",
  12625. " return fig.toolbar_button_onclick(event['data']);\n",
  12626. " }\n",
  12627. " function toolbar_mouse_event(event) {\n",
  12628. " return fig.toolbar_button_onmouseover(event['data']);\n",
  12629. " }\n",
  12630. "\n",
  12631. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  12632. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  12633. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  12634. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  12635. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  12636. "\n",
  12637. " if (!name) {\n",
  12638. " // put a spacer in here.\n",
  12639. " continue;\n",
  12640. " }\n",
  12641. " var button = $('<button/>');\n",
  12642. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  12643. " 'ui-button-icon-only');\n",
  12644. " button.attr('role', 'button');\n",
  12645. " button.attr('aria-disabled', 'false');\n",
  12646. " button.click(method_name, toolbar_event);\n",
  12647. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  12648. "\n",
  12649. " var icon_img = $('<span/>');\n",
  12650. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  12651. " icon_img.addClass(image);\n",
  12652. " icon_img.addClass('ui-corner-all');\n",
  12653. "\n",
  12654. " var tooltip_span = $('<span/>');\n",
  12655. " tooltip_span.addClass('ui-button-text');\n",
  12656. " tooltip_span.html(tooltip);\n",
  12657. "\n",
  12658. " button.append(icon_img);\n",
  12659. " button.append(tooltip_span);\n",
  12660. "\n",
  12661. " nav_element.append(button);\n",
  12662. " }\n",
  12663. "\n",
  12664. " var fmt_picker_span = $('<span/>');\n",
  12665. "\n",
  12666. " var fmt_picker = $('<select/>');\n",
  12667. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  12668. " fmt_picker_span.append(fmt_picker);\n",
  12669. " nav_element.append(fmt_picker_span);\n",
  12670. " this.format_dropdown = fmt_picker[0];\n",
  12671. "\n",
  12672. " for (var ind in mpl.extensions) {\n",
  12673. " var fmt = mpl.extensions[ind];\n",
  12674. " var option = $(\n",
  12675. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  12676. " fmt_picker.append(option)\n",
  12677. " }\n",
  12678. "\n",
  12679. " // Add hover states to the ui-buttons\n",
  12680. " $( \".ui-button\" ).hover(\n",
  12681. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  12682. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  12683. " );\n",
  12684. "\n",
  12685. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  12686. " nav_element.append(status_bar);\n",
  12687. " this.message = status_bar[0];\n",
  12688. "}\n",
  12689. "\n",
  12690. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  12691. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  12692. " // which will in turn request a refresh of the image.\n",
  12693. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  12694. "}\n",
  12695. "\n",
  12696. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  12697. " properties['type'] = type;\n",
  12698. " properties['figure_id'] = this.id;\n",
  12699. " this.ws.send(JSON.stringify(properties));\n",
  12700. "}\n",
  12701. "\n",
  12702. "mpl.figure.prototype.send_draw_message = function() {\n",
  12703. " if (!this.waiting) {\n",
  12704. " this.waiting = true;\n",
  12705. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  12706. " }\n",
  12707. "}\n",
  12708. "\n",
  12709. "\n",
  12710. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  12711. " var format_dropdown = fig.format_dropdown;\n",
  12712. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  12713. " fig.ondownload(fig, format);\n",
  12714. "}\n",
  12715. "\n",
  12716. "\n",
  12717. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  12718. " var size = msg['size'];\n",
  12719. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  12720. " fig._resize_canvas(size[0], size[1]);\n",
  12721. " fig.send_message(\"refresh\", {});\n",
  12722. " };\n",
  12723. "}\n",
  12724. "\n",
  12725. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  12726. " var x0 = msg['x0'] / mpl.ratio;\n",
  12727. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  12728. " var x1 = msg['x1'] / mpl.ratio;\n",
  12729. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  12730. " x0 = Math.floor(x0) + 0.5;\n",
  12731. " y0 = Math.floor(y0) + 0.5;\n",
  12732. " x1 = Math.floor(x1) + 0.5;\n",
  12733. " y1 = Math.floor(y1) + 0.5;\n",
  12734. " var min_x = Math.min(x0, x1);\n",
  12735. " var min_y = Math.min(y0, y1);\n",
  12736. " var width = Math.abs(x1 - x0);\n",
  12737. " var height = Math.abs(y1 - y0);\n",
  12738. "\n",
  12739. " fig.rubberband_context.clearRect(\n",
  12740. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  12741. "\n",
  12742. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  12743. "}\n",
  12744. "\n",
  12745. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  12746. " // Updates the figure title.\n",
  12747. " fig.header.textContent = msg['label'];\n",
  12748. "}\n",
  12749. "\n",
  12750. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  12751. " var cursor = msg['cursor'];\n",
  12752. " switch(cursor)\n",
  12753. " {\n",
  12754. " case 0:\n",
  12755. " cursor = 'pointer';\n",
  12756. " break;\n",
  12757. " case 1:\n",
  12758. " cursor = 'default';\n",
  12759. " break;\n",
  12760. " case 2:\n",
  12761. " cursor = 'crosshair';\n",
  12762. " break;\n",
  12763. " case 3:\n",
  12764. " cursor = 'move';\n",
  12765. " break;\n",
  12766. " }\n",
  12767. " fig.rubberband_canvas.style.cursor = cursor;\n",
  12768. "}\n",
  12769. "\n",
  12770. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  12771. " fig.message.textContent = msg['message'];\n",
  12772. "}\n",
  12773. "\n",
  12774. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  12775. " // Request the server to send over a new figure.\n",
  12776. " fig.send_draw_message();\n",
  12777. "}\n",
  12778. "\n",
  12779. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  12780. " fig.image_mode = msg['mode'];\n",
  12781. "}\n",
  12782. "\n",
  12783. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  12784. " // Called whenever the canvas gets updated.\n",
  12785. " this.send_message(\"ack\", {});\n",
  12786. "}\n",
  12787. "\n",
  12788. "// A function to construct a web socket function for onmessage handling.\n",
  12789. "// Called in the figure constructor.\n",
  12790. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  12791. " return function socket_on_message(evt) {\n",
  12792. " if (evt.data instanceof Blob) {\n",
  12793. " /* FIXME: We get \"Resource interpreted as Image but\n",
  12794. " * transferred with MIME type text/plain:\" errors on\n",
  12795. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  12796. " * to be part of the websocket stream */\n",
  12797. " evt.data.type = \"image/png\";\n",
  12798. "\n",
  12799. " /* Free the memory for the previous frames */\n",
  12800. " if (fig.imageObj.src) {\n",
  12801. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  12802. " fig.imageObj.src);\n",
  12803. " }\n",
  12804. "\n",
  12805. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  12806. " evt.data);\n",
  12807. " fig.updated_canvas_event();\n",
  12808. " fig.waiting = false;\n",
  12809. " return;\n",
  12810. " }\n",
  12811. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  12812. " fig.imageObj.src = evt.data;\n",
  12813. " fig.updated_canvas_event();\n",
  12814. " fig.waiting = false;\n",
  12815. " return;\n",
  12816. " }\n",
  12817. "\n",
  12818. " var msg = JSON.parse(evt.data);\n",
  12819. " var msg_type = msg['type'];\n",
  12820. "\n",
  12821. " // Call the \"handle_{type}\" callback, which takes\n",
  12822. " // the figure and JSON message as its only arguments.\n",
  12823. " try {\n",
  12824. " var callback = fig[\"handle_\" + msg_type];\n",
  12825. " } catch (e) {\n",
  12826. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  12827. " return;\n",
  12828. " }\n",
  12829. "\n",
  12830. " if (callback) {\n",
  12831. " try {\n",
  12832. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  12833. " callback(fig, msg);\n",
  12834. " } catch (e) {\n",
  12835. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  12836. " }\n",
  12837. " }\n",
  12838. " };\n",
  12839. "}\n",
  12840. "\n",
  12841. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  12842. "mpl.findpos = function(e) {\n",
  12843. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  12844. " var targ;\n",
  12845. " if (!e)\n",
  12846. " e = window.event;\n",
  12847. " if (e.target)\n",
  12848. " targ = e.target;\n",
  12849. " else if (e.srcElement)\n",
  12850. " targ = e.srcElement;\n",
  12851. " if (targ.nodeType == 3) // defeat Safari bug\n",
  12852. " targ = targ.parentNode;\n",
  12853. "\n",
  12854. " // jQuery normalizes the pageX and pageY\n",
  12855. " // pageX,Y are the mouse positions relative to the document\n",
  12856. " // offset() returns the position of the element relative to the document\n",
  12857. " var x = e.pageX - $(targ).offset().left;\n",
  12858. " var y = e.pageY - $(targ).offset().top;\n",
  12859. "\n",
  12860. " return {\"x\": x, \"y\": y};\n",
  12861. "};\n",
  12862. "\n",
  12863. "/*\n",
  12864. " * return a copy of an object with only non-object keys\n",
  12865. " * we need this to avoid circular references\n",
  12866. " * http://stackoverflow.com/a/24161582/3208463\n",
  12867. " */\n",
  12868. "function simpleKeys (original) {\n",
  12869. " return Object.keys(original).reduce(function (obj, key) {\n",
  12870. " if (typeof original[key] !== 'object')\n",
  12871. " obj[key] = original[key]\n",
  12872. " return obj;\n",
  12873. " }, {});\n",
  12874. "}\n",
  12875. "\n",
  12876. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  12877. " var canvas_pos = mpl.findpos(event)\n",
  12878. "\n",
  12879. " if (name === 'button_press')\n",
  12880. " {\n",
  12881. " this.canvas.focus();\n",
  12882. " this.canvas_div.focus();\n",
  12883. " }\n",
  12884. "\n",
  12885. " var x = canvas_pos.x * mpl.ratio;\n",
  12886. " var y = canvas_pos.y * mpl.ratio;\n",
  12887. "\n",
  12888. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  12889. " step: event.step,\n",
  12890. " guiEvent: simpleKeys(event)});\n",
  12891. "\n",
  12892. " /* This prevents the web browser from automatically changing to\n",
  12893. " * the text insertion cursor when the button is pressed. We want\n",
  12894. " * to control all of the cursor setting manually through the\n",
  12895. " * 'cursor' event from matplotlib */\n",
  12896. " event.preventDefault();\n",
  12897. " return false;\n",
  12898. "}\n",
  12899. "\n",
  12900. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  12901. " // Handle any extra behaviour associated with a key event\n",
  12902. "}\n",
  12903. "\n",
  12904. "mpl.figure.prototype.key_event = function(event, name) {\n",
  12905. "\n",
  12906. " // Prevent repeat events\n",
  12907. " if (name == 'key_press')\n",
  12908. " {\n",
  12909. " if (event.which === this._key)\n",
  12910. " return;\n",
  12911. " else\n",
  12912. " this._key = event.which;\n",
  12913. " }\n",
  12914. " if (name == 'key_release')\n",
  12915. " this._key = null;\n",
  12916. "\n",
  12917. " var value = '';\n",
  12918. " if (event.ctrlKey && event.which != 17)\n",
  12919. " value += \"ctrl+\";\n",
  12920. " if (event.altKey && event.which != 18)\n",
  12921. " value += \"alt+\";\n",
  12922. " if (event.shiftKey && event.which != 16)\n",
  12923. " value += \"shift+\";\n",
  12924. "\n",
  12925. " value += 'k';\n",
  12926. " value += event.which.toString();\n",
  12927. "\n",
  12928. " this._key_event_extra(event, name);\n",
  12929. "\n",
  12930. " this.send_message(name, {key: value,\n",
  12931. " guiEvent: simpleKeys(event)});\n",
  12932. " return false;\n",
  12933. "}\n",
  12934. "\n",
  12935. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  12936. " if (name == 'download') {\n",
  12937. " this.handle_save(this, null);\n",
  12938. " } else {\n",
  12939. " this.send_message(\"toolbar_button\", {name: name});\n",
  12940. " }\n",
  12941. "};\n",
  12942. "\n",
  12943. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  12944. " this.message.textContent = tooltip;\n",
  12945. "};\n",
  12946. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  12947. "\n",
  12948. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  12949. "\n",
  12950. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  12951. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  12952. " // object with the appropriate methods. Currently this is a non binary\n",
  12953. " // socket, so there is still some room for performance tuning.\n",
  12954. " var ws = {};\n",
  12955. "\n",
  12956. " ws.close = function() {\n",
  12957. " comm.close()\n",
  12958. " };\n",
  12959. " ws.send = function(m) {\n",
  12960. " //console.log('sending', m);\n",
  12961. " comm.send(m);\n",
  12962. " };\n",
  12963. " // Register the callback with on_msg.\n",
  12964. " comm.on_msg(function(msg) {\n",
  12965. " //console.log('receiving', msg['content']['data'], msg);\n",
  12966. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  12967. " ws.onmessage(msg['content']['data'])\n",
  12968. " });\n",
  12969. " return ws;\n",
  12970. "}\n",
  12971. "\n",
  12972. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  12973. " // This is the function which gets called when the mpl process\n",
  12974. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  12975. "\n",
  12976. " var id = msg.content.data.id;\n",
  12977. " // Get hold of the div created by the display call when the Comm\n",
  12978. " // socket was opened in Python.\n",
  12979. " var element = $(\"#\" + id);\n",
  12980. " var ws_proxy = comm_websocket_adapter(comm)\n",
  12981. "\n",
  12982. " function ondownload(figure, format) {\n",
  12983. " window.open(figure.imageObj.src);\n",
  12984. " }\n",
  12985. "\n",
  12986. " var fig = new mpl.figure(id, ws_proxy,\n",
  12987. " ondownload,\n",
  12988. " element.get(0));\n",
  12989. "\n",
  12990. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  12991. " // web socket which is closed, not our websocket->open comm proxy.\n",
  12992. " ws_proxy.onopen();\n",
  12993. "\n",
  12994. " fig.parent_element = element.get(0);\n",
  12995. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  12996. " if (!fig.cell_info) {\n",
  12997. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  12998. " return;\n",
  12999. " }\n",
  13000. "\n",
  13001. " var output_index = fig.cell_info[2]\n",
  13002. " var cell = fig.cell_info[0];\n",
  13003. "\n",
  13004. "};\n",
  13005. "\n",
  13006. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  13007. " var width = fig.canvas.width/mpl.ratio\n",
  13008. " fig.root.unbind('remove')\n",
  13009. "\n",
  13010. " // Update the output cell to use the data from the current canvas.\n",
  13011. " fig.push_to_output();\n",
  13012. " var dataURL = fig.canvas.toDataURL();\n",
  13013. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  13014. " // the notebook keyboard shortcuts fail.\n",
  13015. " IPython.keyboard_manager.enable()\n",
  13016. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  13017. " fig.close_ws(fig, msg);\n",
  13018. "}\n",
  13019. "\n",
  13020. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  13021. " fig.send_message('closing', msg);\n",
  13022. " // fig.ws.close()\n",
  13023. "}\n",
  13024. "\n",
  13025. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  13026. " // Turn the data on the canvas into data in the output cell.\n",
  13027. " var width = this.canvas.width/mpl.ratio\n",
  13028. " var dataURL = this.canvas.toDataURL();\n",
  13029. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  13030. "}\n",
  13031. "\n",
  13032. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  13033. " // Tell IPython that the notebook contents must change.\n",
  13034. " IPython.notebook.set_dirty(true);\n",
  13035. " this.send_message(\"ack\", {});\n",
  13036. " var fig = this;\n",
  13037. " // Wait a second, then push the new image to the DOM so\n",
  13038. " // that it is saved nicely (might be nice to debounce this).\n",
  13039. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  13040. "}\n",
  13041. "\n",
  13042. "mpl.figure.prototype._init_toolbar = function() {\n",
  13043. " var fig = this;\n",
  13044. "\n",
  13045. " var nav_element = $('<div/>')\n",
  13046. " nav_element.attr('style', 'width: 100%');\n",
  13047. " this.root.append(nav_element);\n",
  13048. "\n",
  13049. " // Define a callback function for later on.\n",
  13050. " function toolbar_event(event) {\n",
  13051. " return fig.toolbar_button_onclick(event['data']);\n",
  13052. " }\n",
  13053. " function toolbar_mouse_event(event) {\n",
  13054. " return fig.toolbar_button_onmouseover(event['data']);\n",
  13055. " }\n",
  13056. "\n",
  13057. " for(var toolbar_ind in mpl.toolbar_items){\n",
  13058. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  13059. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  13060. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  13061. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  13062. "\n",
  13063. " if (!name) { continue; };\n",
  13064. "\n",
  13065. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  13066. " button.click(method_name, toolbar_event);\n",
  13067. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  13068. " nav_element.append(button);\n",
  13069. " }\n",
  13070. "\n",
  13071. " // Add the status bar.\n",
  13072. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  13073. " nav_element.append(status_bar);\n",
  13074. " this.message = status_bar[0];\n",
  13075. "\n",
  13076. " // Add the close button to the window.\n",
  13077. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  13078. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  13079. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  13080. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  13081. " buttongrp.append(button);\n",
  13082. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  13083. " titlebar.prepend(buttongrp);\n",
  13084. "}\n",
  13085. "\n",
  13086. "mpl.figure.prototype._root_extra_style = function(el){\n",
  13087. " var fig = this\n",
  13088. " el.on(\"remove\", function(){\n",
  13089. "\tfig.close_ws(fig, {});\n",
  13090. " });\n",
  13091. "}\n",
  13092. "\n",
  13093. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  13094. " // this is important to make the div 'focusable\n",
  13095. " el.attr('tabindex', 0)\n",
  13096. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  13097. " // off when our div gets focus\n",
  13098. "\n",
  13099. " // location in version 3\n",
  13100. " if (IPython.notebook.keyboard_manager) {\n",
  13101. " IPython.notebook.keyboard_manager.register_events(el);\n",
  13102. " }\n",
  13103. " else {\n",
  13104. " // location in version 2\n",
  13105. " IPython.keyboard_manager.register_events(el);\n",
  13106. " }\n",
  13107. "\n",
  13108. "}\n",
  13109. "\n",
  13110. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  13111. " var manager = IPython.notebook.keyboard_manager;\n",
  13112. " if (!manager)\n",
  13113. " manager = IPython.keyboard_manager;\n",
  13114. "\n",
  13115. " // Check for shift+enter\n",
  13116. " if (event.shiftKey && event.which == 13) {\n",
  13117. " this.canvas_div.blur();\n",
  13118. " event.shiftKey = false;\n",
  13119. " // Send a \"J\" for go to next cell\n",
  13120. " event.which = 74;\n",
  13121. " event.keyCode = 74;\n",
  13122. " manager.command_mode();\n",
  13123. " manager.handle_keydown(event);\n",
  13124. " }\n",
  13125. "}\n",
  13126. "\n",
  13127. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  13128. " fig.ondownload(fig, null);\n",
  13129. "}\n",
  13130. "\n",
  13131. "\n",
  13132. "mpl.find_output_cell = function(html_output) {\n",
  13133. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  13134. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  13135. " // IPython event is triggered only after the cells have been serialised, which for\n",
  13136. " // our purposes (turning an active figure into a static one), is too late.\n",
  13137. " var cells = IPython.notebook.get_cells();\n",
  13138. " var ncells = cells.length;\n",
  13139. " for (var i=0; i<ncells; i++) {\n",
  13140. " var cell = cells[i];\n",
  13141. " if (cell.cell_type === 'code'){\n",
  13142. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  13143. " var data = cell.output_area.outputs[j];\n",
  13144. " if (data.data) {\n",
  13145. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  13146. " data = data.data;\n",
  13147. " }\n",
  13148. " if (data['text/html'] == html_output) {\n",
  13149. " return [cell, data, j];\n",
  13150. " }\n",
  13151. " }\n",
  13152. " }\n",
  13153. " }\n",
  13154. "}\n",
  13155. "\n",
  13156. "// Register the function which deals with the matplotlib target/channel.\n",
  13157. "// The kernel may be null if the page has been refreshed.\n",
  13158. "if (IPython.notebook.kernel != null) {\n",
  13159. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  13160. "}\n"
  13161. ],
  13162. "text/plain": [
  13163. "<IPython.core.display.Javascript object>"
  13164. ]
  13165. },
  13166. "metadata": {},
  13167. "output_type": "display_data"
  13168. },
  13169. {
  13170. "data": {
  13171. "text/html": [
  13172. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  13173. ],
  13174. "text/plain": [
  13175. "<IPython.core.display.HTML object>"
  13176. ]
  13177. },
  13178. "metadata": {},
  13179. "output_type": "display_data"
  13180. },
  13181. {
  13182. "name": "stdout",
  13183. "output_type": "stream",
  13184. "text": [
  13185. "0 1\n",
  13186. "803\n",
  13187. "(351, 314)\n",
  13188. "\n"
  13189. ]
  13190. },
  13191. {
  13192. "data": {
  13193. "application/javascript": [
  13194. "/* Put everything inside the global mpl namespace */\n",
  13195. "window.mpl = {};\n",
  13196. "\n",
  13197. "\n",
  13198. "mpl.get_websocket_type = function() {\n",
  13199. " if (typeof(WebSocket) !== 'undefined') {\n",
  13200. " return WebSocket;\n",
  13201. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  13202. " return MozWebSocket;\n",
  13203. " } else {\n",
  13204. " alert('Your browser does not have WebSocket support.' +\n",
  13205. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  13206. " 'Firefox 4 and 5 are also supported but you ' +\n",
  13207. " 'have to enable WebSockets in about:config.');\n",
  13208. " };\n",
  13209. "}\n",
  13210. "\n",
  13211. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  13212. " this.id = figure_id;\n",
  13213. "\n",
  13214. " this.ws = websocket;\n",
  13215. "\n",
  13216. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  13217. "\n",
  13218. " if (!this.supports_binary) {\n",
  13219. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  13220. " if (warnings) {\n",
  13221. " warnings.style.display = 'block';\n",
  13222. " warnings.textContent = (\n",
  13223. " \"This browser does not support binary websocket messages. \" +\n",
  13224. " \"Performance may be slow.\");\n",
  13225. " }\n",
  13226. " }\n",
  13227. "\n",
  13228. " this.imageObj = new Image();\n",
  13229. "\n",
  13230. " this.context = undefined;\n",
  13231. " this.message = undefined;\n",
  13232. " this.canvas = undefined;\n",
  13233. " this.rubberband_canvas = undefined;\n",
  13234. " this.rubberband_context = undefined;\n",
  13235. " this.format_dropdown = undefined;\n",
  13236. "\n",
  13237. " this.image_mode = 'full';\n",
  13238. "\n",
  13239. " this.root = $('<div/>');\n",
  13240. " this._root_extra_style(this.root)\n",
  13241. " this.root.attr('style', 'display: inline-block');\n",
  13242. "\n",
  13243. " $(parent_element).append(this.root);\n",
  13244. "\n",
  13245. " this._init_header(this);\n",
  13246. " this._init_canvas(this);\n",
  13247. " this._init_toolbar(this);\n",
  13248. "\n",
  13249. " var fig = this;\n",
  13250. "\n",
  13251. " this.waiting = false;\n",
  13252. "\n",
  13253. " this.ws.onopen = function () {\n",
  13254. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  13255. " fig.send_message(\"send_image_mode\", {});\n",
  13256. " if (mpl.ratio != 1) {\n",
  13257. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  13258. " }\n",
  13259. " fig.send_message(\"refresh\", {});\n",
  13260. " }\n",
  13261. "\n",
  13262. " this.imageObj.onload = function() {\n",
  13263. " if (fig.image_mode == 'full') {\n",
  13264. " // Full images could contain transparency (where diff images\n",
  13265. " // almost always do), so we need to clear the canvas so that\n",
  13266. " // there is no ghosting.\n",
  13267. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  13268. " }\n",
  13269. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  13270. " };\n",
  13271. "\n",
  13272. " this.imageObj.onunload = function() {\n",
  13273. " fig.ws.close();\n",
  13274. " }\n",
  13275. "\n",
  13276. " this.ws.onmessage = this._make_on_message_function(this);\n",
  13277. "\n",
  13278. " this.ondownload = ondownload;\n",
  13279. "}\n",
  13280. "\n",
  13281. "mpl.figure.prototype._init_header = function() {\n",
  13282. " var titlebar = $(\n",
  13283. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  13284. " 'ui-helper-clearfix\"/>');\n",
  13285. " var titletext = $(\n",
  13286. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  13287. " 'text-align: center; padding: 3px;\"/>');\n",
  13288. " titlebar.append(titletext)\n",
  13289. " this.root.append(titlebar);\n",
  13290. " this.header = titletext[0];\n",
  13291. "}\n",
  13292. "\n",
  13293. "\n",
  13294. "\n",
  13295. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  13296. "\n",
  13297. "}\n",
  13298. "\n",
  13299. "\n",
  13300. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  13301. "\n",
  13302. "}\n",
  13303. "\n",
  13304. "mpl.figure.prototype._init_canvas = function() {\n",
  13305. " var fig = this;\n",
  13306. "\n",
  13307. " var canvas_div = $('<div/>');\n",
  13308. "\n",
  13309. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  13310. "\n",
  13311. " function canvas_keyboard_event(event) {\n",
  13312. " return fig.key_event(event, event['data']);\n",
  13313. " }\n",
  13314. "\n",
  13315. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  13316. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  13317. " this.canvas_div = canvas_div\n",
  13318. " this._canvas_extra_style(canvas_div)\n",
  13319. " this.root.append(canvas_div);\n",
  13320. "\n",
  13321. " var canvas = $('<canvas/>');\n",
  13322. " canvas.addClass('mpl-canvas');\n",
  13323. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  13324. "\n",
  13325. " this.canvas = canvas[0];\n",
  13326. " this.context = canvas[0].getContext(\"2d\");\n",
  13327. "\n",
  13328. " var backingStore = this.context.backingStorePixelRatio ||\n",
  13329. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  13330. "\tthis.context.mozBackingStorePixelRatio ||\n",
  13331. "\tthis.context.msBackingStorePixelRatio ||\n",
  13332. "\tthis.context.oBackingStorePixelRatio ||\n",
  13333. "\tthis.context.backingStorePixelRatio || 1;\n",
  13334. "\n",
  13335. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  13336. "\n",
  13337. " var rubberband = $('<canvas/>');\n",
  13338. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  13339. "\n",
  13340. " var pass_mouse_events = true;\n",
  13341. "\n",
  13342. " canvas_div.resizable({\n",
  13343. " start: function(event, ui) {\n",
  13344. " pass_mouse_events = false;\n",
  13345. " },\n",
  13346. " resize: function(event, ui) {\n",
  13347. " fig.request_resize(ui.size.width, ui.size.height);\n",
  13348. " },\n",
  13349. " stop: function(event, ui) {\n",
  13350. " pass_mouse_events = true;\n",
  13351. " fig.request_resize(ui.size.width, ui.size.height);\n",
  13352. " },\n",
  13353. " });\n",
  13354. "\n",
  13355. " function mouse_event_fn(event) {\n",
  13356. " if (pass_mouse_events)\n",
  13357. " return fig.mouse_event(event, event['data']);\n",
  13358. " }\n",
  13359. "\n",
  13360. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  13361. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  13362. " // Throttle sequential mouse events to 1 every 20ms.\n",
  13363. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  13364. "\n",
  13365. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  13366. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  13367. "\n",
  13368. " canvas_div.on(\"wheel\", function (event) {\n",
  13369. " event = event.originalEvent;\n",
  13370. " event['data'] = 'scroll'\n",
  13371. " if (event.deltaY < 0) {\n",
  13372. " event.step = 1;\n",
  13373. " } else {\n",
  13374. " event.step = -1;\n",
  13375. " }\n",
  13376. " mouse_event_fn(event);\n",
  13377. " });\n",
  13378. "\n",
  13379. " canvas_div.append(canvas);\n",
  13380. " canvas_div.append(rubberband);\n",
  13381. "\n",
  13382. " this.rubberband = rubberband;\n",
  13383. " this.rubberband_canvas = rubberband[0];\n",
  13384. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  13385. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  13386. "\n",
  13387. " this._resize_canvas = function(width, height) {\n",
  13388. " // Keep the size of the canvas, canvas container, and rubber band\n",
  13389. " // canvas in synch.\n",
  13390. " canvas_div.css('width', width)\n",
  13391. " canvas_div.css('height', height)\n",
  13392. "\n",
  13393. " canvas.attr('width', width * mpl.ratio);\n",
  13394. " canvas.attr('height', height * mpl.ratio);\n",
  13395. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  13396. "\n",
  13397. " rubberband.attr('width', width);\n",
  13398. " rubberband.attr('height', height);\n",
  13399. " }\n",
  13400. "\n",
  13401. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  13402. " // upon first draw.\n",
  13403. " this._resize_canvas(600, 600);\n",
  13404. "\n",
  13405. " // Disable right mouse context menu.\n",
  13406. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  13407. " return false;\n",
  13408. " });\n",
  13409. "\n",
  13410. " function set_focus () {\n",
  13411. " canvas.focus();\n",
  13412. " canvas_div.focus();\n",
  13413. " }\n",
  13414. "\n",
  13415. " window.setTimeout(set_focus, 100);\n",
  13416. "}\n",
  13417. "\n",
  13418. "mpl.figure.prototype._init_toolbar = function() {\n",
  13419. " var fig = this;\n",
  13420. "\n",
  13421. " var nav_element = $('<div/>')\n",
  13422. " nav_element.attr('style', 'width: 100%');\n",
  13423. " this.root.append(nav_element);\n",
  13424. "\n",
  13425. " // Define a callback function for later on.\n",
  13426. " function toolbar_event(event) {\n",
  13427. " return fig.toolbar_button_onclick(event['data']);\n",
  13428. " }\n",
  13429. " function toolbar_mouse_event(event) {\n",
  13430. " return fig.toolbar_button_onmouseover(event['data']);\n",
  13431. " }\n",
  13432. "\n",
  13433. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  13434. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  13435. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  13436. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  13437. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  13438. "\n",
  13439. " if (!name) {\n",
  13440. " // put a spacer in here.\n",
  13441. " continue;\n",
  13442. " }\n",
  13443. " var button = $('<button/>');\n",
  13444. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  13445. " 'ui-button-icon-only');\n",
  13446. " button.attr('role', 'button');\n",
  13447. " button.attr('aria-disabled', 'false');\n",
  13448. " button.click(method_name, toolbar_event);\n",
  13449. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  13450. "\n",
  13451. " var icon_img = $('<span/>');\n",
  13452. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  13453. " icon_img.addClass(image);\n",
  13454. " icon_img.addClass('ui-corner-all');\n",
  13455. "\n",
  13456. " var tooltip_span = $('<span/>');\n",
  13457. " tooltip_span.addClass('ui-button-text');\n",
  13458. " tooltip_span.html(tooltip);\n",
  13459. "\n",
  13460. " button.append(icon_img);\n",
  13461. " button.append(tooltip_span);\n",
  13462. "\n",
  13463. " nav_element.append(button);\n",
  13464. " }\n",
  13465. "\n",
  13466. " var fmt_picker_span = $('<span/>');\n",
  13467. "\n",
  13468. " var fmt_picker = $('<select/>');\n",
  13469. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  13470. " fmt_picker_span.append(fmt_picker);\n",
  13471. " nav_element.append(fmt_picker_span);\n",
  13472. " this.format_dropdown = fmt_picker[0];\n",
  13473. "\n",
  13474. " for (var ind in mpl.extensions) {\n",
  13475. " var fmt = mpl.extensions[ind];\n",
  13476. " var option = $(\n",
  13477. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  13478. " fmt_picker.append(option)\n",
  13479. " }\n",
  13480. "\n",
  13481. " // Add hover states to the ui-buttons\n",
  13482. " $( \".ui-button\" ).hover(\n",
  13483. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  13484. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  13485. " );\n",
  13486. "\n",
  13487. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  13488. " nav_element.append(status_bar);\n",
  13489. " this.message = status_bar[0];\n",
  13490. "}\n",
  13491. "\n",
  13492. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  13493. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  13494. " // which will in turn request a refresh of the image.\n",
  13495. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  13496. "}\n",
  13497. "\n",
  13498. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  13499. " properties['type'] = type;\n",
  13500. " properties['figure_id'] = this.id;\n",
  13501. " this.ws.send(JSON.stringify(properties));\n",
  13502. "}\n",
  13503. "\n",
  13504. "mpl.figure.prototype.send_draw_message = function() {\n",
  13505. " if (!this.waiting) {\n",
  13506. " this.waiting = true;\n",
  13507. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  13508. " }\n",
  13509. "}\n",
  13510. "\n",
  13511. "\n",
  13512. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  13513. " var format_dropdown = fig.format_dropdown;\n",
  13514. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  13515. " fig.ondownload(fig, format);\n",
  13516. "}\n",
  13517. "\n",
  13518. "\n",
  13519. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  13520. " var size = msg['size'];\n",
  13521. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  13522. " fig._resize_canvas(size[0], size[1]);\n",
  13523. " fig.send_message(\"refresh\", {});\n",
  13524. " };\n",
  13525. "}\n",
  13526. "\n",
  13527. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  13528. " var x0 = msg['x0'] / mpl.ratio;\n",
  13529. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  13530. " var x1 = msg['x1'] / mpl.ratio;\n",
  13531. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  13532. " x0 = Math.floor(x0) + 0.5;\n",
  13533. " y0 = Math.floor(y0) + 0.5;\n",
  13534. " x1 = Math.floor(x1) + 0.5;\n",
  13535. " y1 = Math.floor(y1) + 0.5;\n",
  13536. " var min_x = Math.min(x0, x1);\n",
  13537. " var min_y = Math.min(y0, y1);\n",
  13538. " var width = Math.abs(x1 - x0);\n",
  13539. " var height = Math.abs(y1 - y0);\n",
  13540. "\n",
  13541. " fig.rubberband_context.clearRect(\n",
  13542. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  13543. "\n",
  13544. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  13545. "}\n",
  13546. "\n",
  13547. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  13548. " // Updates the figure title.\n",
  13549. " fig.header.textContent = msg['label'];\n",
  13550. "}\n",
  13551. "\n",
  13552. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  13553. " var cursor = msg['cursor'];\n",
  13554. " switch(cursor)\n",
  13555. " {\n",
  13556. " case 0:\n",
  13557. " cursor = 'pointer';\n",
  13558. " break;\n",
  13559. " case 1:\n",
  13560. " cursor = 'default';\n",
  13561. " break;\n",
  13562. " case 2:\n",
  13563. " cursor = 'crosshair';\n",
  13564. " break;\n",
  13565. " case 3:\n",
  13566. " cursor = 'move';\n",
  13567. " break;\n",
  13568. " }\n",
  13569. " fig.rubberband_canvas.style.cursor = cursor;\n",
  13570. "}\n",
  13571. "\n",
  13572. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  13573. " fig.message.textContent = msg['message'];\n",
  13574. "}\n",
  13575. "\n",
  13576. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  13577. " // Request the server to send over a new figure.\n",
  13578. " fig.send_draw_message();\n",
  13579. "}\n",
  13580. "\n",
  13581. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  13582. " fig.image_mode = msg['mode'];\n",
  13583. "}\n",
  13584. "\n",
  13585. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  13586. " // Called whenever the canvas gets updated.\n",
  13587. " this.send_message(\"ack\", {});\n",
  13588. "}\n",
  13589. "\n",
  13590. "// A function to construct a web socket function for onmessage handling.\n",
  13591. "// Called in the figure constructor.\n",
  13592. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  13593. " return function socket_on_message(evt) {\n",
  13594. " if (evt.data instanceof Blob) {\n",
  13595. " /* FIXME: We get \"Resource interpreted as Image but\n",
  13596. " * transferred with MIME type text/plain:\" errors on\n",
  13597. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  13598. " * to be part of the websocket stream */\n",
  13599. " evt.data.type = \"image/png\";\n",
  13600. "\n",
  13601. " /* Free the memory for the previous frames */\n",
  13602. " if (fig.imageObj.src) {\n",
  13603. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  13604. " fig.imageObj.src);\n",
  13605. " }\n",
  13606. "\n",
  13607. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  13608. " evt.data);\n",
  13609. " fig.updated_canvas_event();\n",
  13610. " fig.waiting = false;\n",
  13611. " return;\n",
  13612. " }\n",
  13613. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  13614. " fig.imageObj.src = evt.data;\n",
  13615. " fig.updated_canvas_event();\n",
  13616. " fig.waiting = false;\n",
  13617. " return;\n",
  13618. " }\n",
  13619. "\n",
  13620. " var msg = JSON.parse(evt.data);\n",
  13621. " var msg_type = msg['type'];\n",
  13622. "\n",
  13623. " // Call the \"handle_{type}\" callback, which takes\n",
  13624. " // the figure and JSON message as its only arguments.\n",
  13625. " try {\n",
  13626. " var callback = fig[\"handle_\" + msg_type];\n",
  13627. " } catch (e) {\n",
  13628. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  13629. " return;\n",
  13630. " }\n",
  13631. "\n",
  13632. " if (callback) {\n",
  13633. " try {\n",
  13634. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  13635. " callback(fig, msg);\n",
  13636. " } catch (e) {\n",
  13637. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  13638. " }\n",
  13639. " }\n",
  13640. " };\n",
  13641. "}\n",
  13642. "\n",
  13643. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  13644. "mpl.findpos = function(e) {\n",
  13645. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  13646. " var targ;\n",
  13647. " if (!e)\n",
  13648. " e = window.event;\n",
  13649. " if (e.target)\n",
  13650. " targ = e.target;\n",
  13651. " else if (e.srcElement)\n",
  13652. " targ = e.srcElement;\n",
  13653. " if (targ.nodeType == 3) // defeat Safari bug\n",
  13654. " targ = targ.parentNode;\n",
  13655. "\n",
  13656. " // jQuery normalizes the pageX and pageY\n",
  13657. " // pageX,Y are the mouse positions relative to the document\n",
  13658. " // offset() returns the position of the element relative to the document\n",
  13659. " var x = e.pageX - $(targ).offset().left;\n",
  13660. " var y = e.pageY - $(targ).offset().top;\n",
  13661. "\n",
  13662. " return {\"x\": x, \"y\": y};\n",
  13663. "};\n",
  13664. "\n",
  13665. "/*\n",
  13666. " * return a copy of an object with only non-object keys\n",
  13667. " * we need this to avoid circular references\n",
  13668. " * http://stackoverflow.com/a/24161582/3208463\n",
  13669. " */\n",
  13670. "function simpleKeys (original) {\n",
  13671. " return Object.keys(original).reduce(function (obj, key) {\n",
  13672. " if (typeof original[key] !== 'object')\n",
  13673. " obj[key] = original[key]\n",
  13674. " return obj;\n",
  13675. " }, {});\n",
  13676. "}\n",
  13677. "\n",
  13678. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  13679. " var canvas_pos = mpl.findpos(event)\n",
  13680. "\n",
  13681. " if (name === 'button_press')\n",
  13682. " {\n",
  13683. " this.canvas.focus();\n",
  13684. " this.canvas_div.focus();\n",
  13685. " }\n",
  13686. "\n",
  13687. " var x = canvas_pos.x * mpl.ratio;\n",
  13688. " var y = canvas_pos.y * mpl.ratio;\n",
  13689. "\n",
  13690. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  13691. " step: event.step,\n",
  13692. " guiEvent: simpleKeys(event)});\n",
  13693. "\n",
  13694. " /* This prevents the web browser from automatically changing to\n",
  13695. " * the text insertion cursor when the button is pressed. We want\n",
  13696. " * to control all of the cursor setting manually through the\n",
  13697. " * 'cursor' event from matplotlib */\n",
  13698. " event.preventDefault();\n",
  13699. " return false;\n",
  13700. "}\n",
  13701. "\n",
  13702. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  13703. " // Handle any extra behaviour associated with a key event\n",
  13704. "}\n",
  13705. "\n",
  13706. "mpl.figure.prototype.key_event = function(event, name) {\n",
  13707. "\n",
  13708. " // Prevent repeat events\n",
  13709. " if (name == 'key_press')\n",
  13710. " {\n",
  13711. " if (event.which === this._key)\n",
  13712. " return;\n",
  13713. " else\n",
  13714. " this._key = event.which;\n",
  13715. " }\n",
  13716. " if (name == 'key_release')\n",
  13717. " this._key = null;\n",
  13718. "\n",
  13719. " var value = '';\n",
  13720. " if (event.ctrlKey && event.which != 17)\n",
  13721. " value += \"ctrl+\";\n",
  13722. " if (event.altKey && event.which != 18)\n",
  13723. " value += \"alt+\";\n",
  13724. " if (event.shiftKey && event.which != 16)\n",
  13725. " value += \"shift+\";\n",
  13726. "\n",
  13727. " value += 'k';\n",
  13728. " value += event.which.toString();\n",
  13729. "\n",
  13730. " this._key_event_extra(event, name);\n",
  13731. "\n",
  13732. " this.send_message(name, {key: value,\n",
  13733. " guiEvent: simpleKeys(event)});\n",
  13734. " return false;\n",
  13735. "}\n",
  13736. "\n",
  13737. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  13738. " if (name == 'download') {\n",
  13739. " this.handle_save(this, null);\n",
  13740. " } else {\n",
  13741. " this.send_message(\"toolbar_button\", {name: name});\n",
  13742. " }\n",
  13743. "};\n",
  13744. "\n",
  13745. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  13746. " this.message.textContent = tooltip;\n",
  13747. "};\n",
  13748. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  13749. "\n",
  13750. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  13751. "\n",
  13752. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  13753. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  13754. " // object with the appropriate methods. Currently this is a non binary\n",
  13755. " // socket, so there is still some room for performance tuning.\n",
  13756. " var ws = {};\n",
  13757. "\n",
  13758. " ws.close = function() {\n",
  13759. " comm.close()\n",
  13760. " };\n",
  13761. " ws.send = function(m) {\n",
  13762. " //console.log('sending', m);\n",
  13763. " comm.send(m);\n",
  13764. " };\n",
  13765. " // Register the callback with on_msg.\n",
  13766. " comm.on_msg(function(msg) {\n",
  13767. " //console.log('receiving', msg['content']['data'], msg);\n",
  13768. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  13769. " ws.onmessage(msg['content']['data'])\n",
  13770. " });\n",
  13771. " return ws;\n",
  13772. "}\n",
  13773. "\n",
  13774. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  13775. " // This is the function which gets called when the mpl process\n",
  13776. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  13777. "\n",
  13778. " var id = msg.content.data.id;\n",
  13779. " // Get hold of the div created by the display call when the Comm\n",
  13780. " // socket was opened in Python.\n",
  13781. " var element = $(\"#\" + id);\n",
  13782. " var ws_proxy = comm_websocket_adapter(comm)\n",
  13783. "\n",
  13784. " function ondownload(figure, format) {\n",
  13785. " window.open(figure.imageObj.src);\n",
  13786. " }\n",
  13787. "\n",
  13788. " var fig = new mpl.figure(id, ws_proxy,\n",
  13789. " ondownload,\n",
  13790. " element.get(0));\n",
  13791. "\n",
  13792. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  13793. " // web socket which is closed, not our websocket->open comm proxy.\n",
  13794. " ws_proxy.onopen();\n",
  13795. "\n",
  13796. " fig.parent_element = element.get(0);\n",
  13797. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  13798. " if (!fig.cell_info) {\n",
  13799. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  13800. " return;\n",
  13801. " }\n",
  13802. "\n",
  13803. " var output_index = fig.cell_info[2]\n",
  13804. " var cell = fig.cell_info[0];\n",
  13805. "\n",
  13806. "};\n",
  13807. "\n",
  13808. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  13809. " var width = fig.canvas.width/mpl.ratio\n",
  13810. " fig.root.unbind('remove')\n",
  13811. "\n",
  13812. " // Update the output cell to use the data from the current canvas.\n",
  13813. " fig.push_to_output();\n",
  13814. " var dataURL = fig.canvas.toDataURL();\n",
  13815. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  13816. " // the notebook keyboard shortcuts fail.\n",
  13817. " IPython.keyboard_manager.enable()\n",
  13818. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  13819. " fig.close_ws(fig, msg);\n",
  13820. "}\n",
  13821. "\n",
  13822. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  13823. " fig.send_message('closing', msg);\n",
  13824. " // fig.ws.close()\n",
  13825. "}\n",
  13826. "\n",
  13827. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  13828. " // Turn the data on the canvas into data in the output cell.\n",
  13829. " var width = this.canvas.width/mpl.ratio\n",
  13830. " var dataURL = this.canvas.toDataURL();\n",
  13831. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  13832. "}\n",
  13833. "\n",
  13834. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  13835. " // Tell IPython that the notebook contents must change.\n",
  13836. " IPython.notebook.set_dirty(true);\n",
  13837. " this.send_message(\"ack\", {});\n",
  13838. " var fig = this;\n",
  13839. " // Wait a second, then push the new image to the DOM so\n",
  13840. " // that it is saved nicely (might be nice to debounce this).\n",
  13841. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  13842. "}\n",
  13843. "\n",
  13844. "mpl.figure.prototype._init_toolbar = function() {\n",
  13845. " var fig = this;\n",
  13846. "\n",
  13847. " var nav_element = $('<div/>')\n",
  13848. " nav_element.attr('style', 'width: 100%');\n",
  13849. " this.root.append(nav_element);\n",
  13850. "\n",
  13851. " // Define a callback function for later on.\n",
  13852. " function toolbar_event(event) {\n",
  13853. " return fig.toolbar_button_onclick(event['data']);\n",
  13854. " }\n",
  13855. " function toolbar_mouse_event(event) {\n",
  13856. " return fig.toolbar_button_onmouseover(event['data']);\n",
  13857. " }\n",
  13858. "\n",
  13859. " for(var toolbar_ind in mpl.toolbar_items){\n",
  13860. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  13861. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  13862. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  13863. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  13864. "\n",
  13865. " if (!name) { continue; };\n",
  13866. "\n",
  13867. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  13868. " button.click(method_name, toolbar_event);\n",
  13869. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  13870. " nav_element.append(button);\n",
  13871. " }\n",
  13872. "\n",
  13873. " // Add the status bar.\n",
  13874. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  13875. " nav_element.append(status_bar);\n",
  13876. " this.message = status_bar[0];\n",
  13877. "\n",
  13878. " // Add the close button to the window.\n",
  13879. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  13880. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  13881. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  13882. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  13883. " buttongrp.append(button);\n",
  13884. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  13885. " titlebar.prepend(buttongrp);\n",
  13886. "}\n",
  13887. "\n",
  13888. "mpl.figure.prototype._root_extra_style = function(el){\n",
  13889. " var fig = this\n",
  13890. " el.on(\"remove\", function(){\n",
  13891. "\tfig.close_ws(fig, {});\n",
  13892. " });\n",
  13893. "}\n",
  13894. "\n",
  13895. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  13896. " // this is important to make the div 'focusable\n",
  13897. " el.attr('tabindex', 0)\n",
  13898. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  13899. " // off when our div gets focus\n",
  13900. "\n",
  13901. " // location in version 3\n",
  13902. " if (IPython.notebook.keyboard_manager) {\n",
  13903. " IPython.notebook.keyboard_manager.register_events(el);\n",
  13904. " }\n",
  13905. " else {\n",
  13906. " // location in version 2\n",
  13907. " IPython.keyboard_manager.register_events(el);\n",
  13908. " }\n",
  13909. "\n",
  13910. "}\n",
  13911. "\n",
  13912. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  13913. " var manager = IPython.notebook.keyboard_manager;\n",
  13914. " if (!manager)\n",
  13915. " manager = IPython.keyboard_manager;\n",
  13916. "\n",
  13917. " // Check for shift+enter\n",
  13918. " if (event.shiftKey && event.which == 13) {\n",
  13919. " this.canvas_div.blur();\n",
  13920. " event.shiftKey = false;\n",
  13921. " // Send a \"J\" for go to next cell\n",
  13922. " event.which = 74;\n",
  13923. " event.keyCode = 74;\n",
  13924. " manager.command_mode();\n",
  13925. " manager.handle_keydown(event);\n",
  13926. " }\n",
  13927. "}\n",
  13928. "\n",
  13929. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  13930. " fig.ondownload(fig, null);\n",
  13931. "}\n",
  13932. "\n",
  13933. "\n",
  13934. "mpl.find_output_cell = function(html_output) {\n",
  13935. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  13936. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  13937. " // IPython event is triggered only after the cells have been serialised, which for\n",
  13938. " // our purposes (turning an active figure into a static one), is too late.\n",
  13939. " var cells = IPython.notebook.get_cells();\n",
  13940. " var ncells = cells.length;\n",
  13941. " for (var i=0; i<ncells; i++) {\n",
  13942. " var cell = cells[i];\n",
  13943. " if (cell.cell_type === 'code'){\n",
  13944. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  13945. " var data = cell.output_area.outputs[j];\n",
  13946. " if (data.data) {\n",
  13947. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  13948. " data = data.data;\n",
  13949. " }\n",
  13950. " if (data['text/html'] == html_output) {\n",
  13951. " return [cell, data, j];\n",
  13952. " }\n",
  13953. " }\n",
  13954. " }\n",
  13955. " }\n",
  13956. "}\n",
  13957. "\n",
  13958. "// Register the function which deals with the matplotlib target/channel.\n",
  13959. "// The kernel may be null if the page has been refreshed.\n",
  13960. "if (IPython.notebook.kernel != null) {\n",
  13961. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  13962. "}\n"
  13963. ],
  13964. "text/plain": [
  13965. "<IPython.core.display.Javascript object>"
  13966. ]
  13967. },
  13968. "metadata": {},
  13969. "output_type": "display_data"
  13970. },
  13971. {
  13972. "data": {
  13973. "text/html": [
  13974. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  13975. ],
  13976. "text/plain": [
  13977. "<IPython.core.display.HTML object>"
  13978. ]
  13979. },
  13980. "metadata": {},
  13981. "output_type": "display_data"
  13982. },
  13983. {
  13984. "name": "stdout",
  13985. "output_type": "stream",
  13986. "text": [
  13987. "0.0 1.0\n",
  13988. "786.9918\n",
  13989. "(370, 313)\n",
  13990. "\n"
  13991. ]
  13992. },
  13993. {
  13994. "data": {
  13995. "application/javascript": [
  13996. "/* Put everything inside the global mpl namespace */\n",
  13997. "window.mpl = {};\n",
  13998. "\n",
  13999. "\n",
  14000. "mpl.get_websocket_type = function() {\n",
  14001. " if (typeof(WebSocket) !== 'undefined') {\n",
  14002. " return WebSocket;\n",
  14003. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  14004. " return MozWebSocket;\n",
  14005. " } else {\n",
  14006. " alert('Your browser does not have WebSocket support.' +\n",
  14007. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  14008. " 'Firefox 4 and 5 are also supported but you ' +\n",
  14009. " 'have to enable WebSockets in about:config.');\n",
  14010. " };\n",
  14011. "}\n",
  14012. "\n",
  14013. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  14014. " this.id = figure_id;\n",
  14015. "\n",
  14016. " this.ws = websocket;\n",
  14017. "\n",
  14018. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  14019. "\n",
  14020. " if (!this.supports_binary) {\n",
  14021. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  14022. " if (warnings) {\n",
  14023. " warnings.style.display = 'block';\n",
  14024. " warnings.textContent = (\n",
  14025. " \"This browser does not support binary websocket messages. \" +\n",
  14026. " \"Performance may be slow.\");\n",
  14027. " }\n",
  14028. " }\n",
  14029. "\n",
  14030. " this.imageObj = new Image();\n",
  14031. "\n",
  14032. " this.context = undefined;\n",
  14033. " this.message = undefined;\n",
  14034. " this.canvas = undefined;\n",
  14035. " this.rubberband_canvas = undefined;\n",
  14036. " this.rubberband_context = undefined;\n",
  14037. " this.format_dropdown = undefined;\n",
  14038. "\n",
  14039. " this.image_mode = 'full';\n",
  14040. "\n",
  14041. " this.root = $('<div/>');\n",
  14042. " this._root_extra_style(this.root)\n",
  14043. " this.root.attr('style', 'display: inline-block');\n",
  14044. "\n",
  14045. " $(parent_element).append(this.root);\n",
  14046. "\n",
  14047. " this._init_header(this);\n",
  14048. " this._init_canvas(this);\n",
  14049. " this._init_toolbar(this);\n",
  14050. "\n",
  14051. " var fig = this;\n",
  14052. "\n",
  14053. " this.waiting = false;\n",
  14054. "\n",
  14055. " this.ws.onopen = function () {\n",
  14056. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  14057. " fig.send_message(\"send_image_mode\", {});\n",
  14058. " if (mpl.ratio != 1) {\n",
  14059. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  14060. " }\n",
  14061. " fig.send_message(\"refresh\", {});\n",
  14062. " }\n",
  14063. "\n",
  14064. " this.imageObj.onload = function() {\n",
  14065. " if (fig.image_mode == 'full') {\n",
  14066. " // Full images could contain transparency (where diff images\n",
  14067. " // almost always do), so we need to clear the canvas so that\n",
  14068. " // there is no ghosting.\n",
  14069. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  14070. " }\n",
  14071. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  14072. " };\n",
  14073. "\n",
  14074. " this.imageObj.onunload = function() {\n",
  14075. " fig.ws.close();\n",
  14076. " }\n",
  14077. "\n",
  14078. " this.ws.onmessage = this._make_on_message_function(this);\n",
  14079. "\n",
  14080. " this.ondownload = ondownload;\n",
  14081. "}\n",
  14082. "\n",
  14083. "mpl.figure.prototype._init_header = function() {\n",
  14084. " var titlebar = $(\n",
  14085. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  14086. " 'ui-helper-clearfix\"/>');\n",
  14087. " var titletext = $(\n",
  14088. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  14089. " 'text-align: center; padding: 3px;\"/>');\n",
  14090. " titlebar.append(titletext)\n",
  14091. " this.root.append(titlebar);\n",
  14092. " this.header = titletext[0];\n",
  14093. "}\n",
  14094. "\n",
  14095. "\n",
  14096. "\n",
  14097. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  14098. "\n",
  14099. "}\n",
  14100. "\n",
  14101. "\n",
  14102. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  14103. "\n",
  14104. "}\n",
  14105. "\n",
  14106. "mpl.figure.prototype._init_canvas = function() {\n",
  14107. " var fig = this;\n",
  14108. "\n",
  14109. " var canvas_div = $('<div/>');\n",
  14110. "\n",
  14111. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  14112. "\n",
  14113. " function canvas_keyboard_event(event) {\n",
  14114. " return fig.key_event(event, event['data']);\n",
  14115. " }\n",
  14116. "\n",
  14117. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  14118. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  14119. " this.canvas_div = canvas_div\n",
  14120. " this._canvas_extra_style(canvas_div)\n",
  14121. " this.root.append(canvas_div);\n",
  14122. "\n",
  14123. " var canvas = $('<canvas/>');\n",
  14124. " canvas.addClass('mpl-canvas');\n",
  14125. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  14126. "\n",
  14127. " this.canvas = canvas[0];\n",
  14128. " this.context = canvas[0].getContext(\"2d\");\n",
  14129. "\n",
  14130. " var backingStore = this.context.backingStorePixelRatio ||\n",
  14131. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  14132. "\tthis.context.mozBackingStorePixelRatio ||\n",
  14133. "\tthis.context.msBackingStorePixelRatio ||\n",
  14134. "\tthis.context.oBackingStorePixelRatio ||\n",
  14135. "\tthis.context.backingStorePixelRatio || 1;\n",
  14136. "\n",
  14137. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  14138. "\n",
  14139. " var rubberband = $('<canvas/>');\n",
  14140. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  14141. "\n",
  14142. " var pass_mouse_events = true;\n",
  14143. "\n",
  14144. " canvas_div.resizable({\n",
  14145. " start: function(event, ui) {\n",
  14146. " pass_mouse_events = false;\n",
  14147. " },\n",
  14148. " resize: function(event, ui) {\n",
  14149. " fig.request_resize(ui.size.width, ui.size.height);\n",
  14150. " },\n",
  14151. " stop: function(event, ui) {\n",
  14152. " pass_mouse_events = true;\n",
  14153. " fig.request_resize(ui.size.width, ui.size.height);\n",
  14154. " },\n",
  14155. " });\n",
  14156. "\n",
  14157. " function mouse_event_fn(event) {\n",
  14158. " if (pass_mouse_events)\n",
  14159. " return fig.mouse_event(event, event['data']);\n",
  14160. " }\n",
  14161. "\n",
  14162. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  14163. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  14164. " // Throttle sequential mouse events to 1 every 20ms.\n",
  14165. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  14166. "\n",
  14167. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  14168. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  14169. "\n",
  14170. " canvas_div.on(\"wheel\", function (event) {\n",
  14171. " event = event.originalEvent;\n",
  14172. " event['data'] = 'scroll'\n",
  14173. " if (event.deltaY < 0) {\n",
  14174. " event.step = 1;\n",
  14175. " } else {\n",
  14176. " event.step = -1;\n",
  14177. " }\n",
  14178. " mouse_event_fn(event);\n",
  14179. " });\n",
  14180. "\n",
  14181. " canvas_div.append(canvas);\n",
  14182. " canvas_div.append(rubberband);\n",
  14183. "\n",
  14184. " this.rubberband = rubberband;\n",
  14185. " this.rubberband_canvas = rubberband[0];\n",
  14186. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  14187. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  14188. "\n",
  14189. " this._resize_canvas = function(width, height) {\n",
  14190. " // Keep the size of the canvas, canvas container, and rubber band\n",
  14191. " // canvas in synch.\n",
  14192. " canvas_div.css('width', width)\n",
  14193. " canvas_div.css('height', height)\n",
  14194. "\n",
  14195. " canvas.attr('width', width * mpl.ratio);\n",
  14196. " canvas.attr('height', height * mpl.ratio);\n",
  14197. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  14198. "\n",
  14199. " rubberband.attr('width', width);\n",
  14200. " rubberband.attr('height', height);\n",
  14201. " }\n",
  14202. "\n",
  14203. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  14204. " // upon first draw.\n",
  14205. " this._resize_canvas(600, 600);\n",
  14206. "\n",
  14207. " // Disable right mouse context menu.\n",
  14208. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  14209. " return false;\n",
  14210. " });\n",
  14211. "\n",
  14212. " function set_focus () {\n",
  14213. " canvas.focus();\n",
  14214. " canvas_div.focus();\n",
  14215. " }\n",
  14216. "\n",
  14217. " window.setTimeout(set_focus, 100);\n",
  14218. "}\n",
  14219. "\n",
  14220. "mpl.figure.prototype._init_toolbar = function() {\n",
  14221. " var fig = this;\n",
  14222. "\n",
  14223. " var nav_element = $('<div/>')\n",
  14224. " nav_element.attr('style', 'width: 100%');\n",
  14225. " this.root.append(nav_element);\n",
  14226. "\n",
  14227. " // Define a callback function for later on.\n",
  14228. " function toolbar_event(event) {\n",
  14229. " return fig.toolbar_button_onclick(event['data']);\n",
  14230. " }\n",
  14231. " function toolbar_mouse_event(event) {\n",
  14232. " return fig.toolbar_button_onmouseover(event['data']);\n",
  14233. " }\n",
  14234. "\n",
  14235. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  14236. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  14237. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  14238. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  14239. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  14240. "\n",
  14241. " if (!name) {\n",
  14242. " // put a spacer in here.\n",
  14243. " continue;\n",
  14244. " }\n",
  14245. " var button = $('<button/>');\n",
  14246. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  14247. " 'ui-button-icon-only');\n",
  14248. " button.attr('role', 'button');\n",
  14249. " button.attr('aria-disabled', 'false');\n",
  14250. " button.click(method_name, toolbar_event);\n",
  14251. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  14252. "\n",
  14253. " var icon_img = $('<span/>');\n",
  14254. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  14255. " icon_img.addClass(image);\n",
  14256. " icon_img.addClass('ui-corner-all');\n",
  14257. "\n",
  14258. " var tooltip_span = $('<span/>');\n",
  14259. " tooltip_span.addClass('ui-button-text');\n",
  14260. " tooltip_span.html(tooltip);\n",
  14261. "\n",
  14262. " button.append(icon_img);\n",
  14263. " button.append(tooltip_span);\n",
  14264. "\n",
  14265. " nav_element.append(button);\n",
  14266. " }\n",
  14267. "\n",
  14268. " var fmt_picker_span = $('<span/>');\n",
  14269. "\n",
  14270. " var fmt_picker = $('<select/>');\n",
  14271. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  14272. " fmt_picker_span.append(fmt_picker);\n",
  14273. " nav_element.append(fmt_picker_span);\n",
  14274. " this.format_dropdown = fmt_picker[0];\n",
  14275. "\n",
  14276. " for (var ind in mpl.extensions) {\n",
  14277. " var fmt = mpl.extensions[ind];\n",
  14278. " var option = $(\n",
  14279. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  14280. " fmt_picker.append(option)\n",
  14281. " }\n",
  14282. "\n",
  14283. " // Add hover states to the ui-buttons\n",
  14284. " $( \".ui-button\" ).hover(\n",
  14285. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  14286. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  14287. " );\n",
  14288. "\n",
  14289. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  14290. " nav_element.append(status_bar);\n",
  14291. " this.message = status_bar[0];\n",
  14292. "}\n",
  14293. "\n",
  14294. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  14295. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  14296. " // which will in turn request a refresh of the image.\n",
  14297. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  14298. "}\n",
  14299. "\n",
  14300. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  14301. " properties['type'] = type;\n",
  14302. " properties['figure_id'] = this.id;\n",
  14303. " this.ws.send(JSON.stringify(properties));\n",
  14304. "}\n",
  14305. "\n",
  14306. "mpl.figure.prototype.send_draw_message = function() {\n",
  14307. " if (!this.waiting) {\n",
  14308. " this.waiting = true;\n",
  14309. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  14310. " }\n",
  14311. "}\n",
  14312. "\n",
  14313. "\n",
  14314. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  14315. " var format_dropdown = fig.format_dropdown;\n",
  14316. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  14317. " fig.ondownload(fig, format);\n",
  14318. "}\n",
  14319. "\n",
  14320. "\n",
  14321. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  14322. " var size = msg['size'];\n",
  14323. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  14324. " fig._resize_canvas(size[0], size[1]);\n",
  14325. " fig.send_message(\"refresh\", {});\n",
  14326. " };\n",
  14327. "}\n",
  14328. "\n",
  14329. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  14330. " var x0 = msg['x0'] / mpl.ratio;\n",
  14331. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  14332. " var x1 = msg['x1'] / mpl.ratio;\n",
  14333. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  14334. " x0 = Math.floor(x0) + 0.5;\n",
  14335. " y0 = Math.floor(y0) + 0.5;\n",
  14336. " x1 = Math.floor(x1) + 0.5;\n",
  14337. " y1 = Math.floor(y1) + 0.5;\n",
  14338. " var min_x = Math.min(x0, x1);\n",
  14339. " var min_y = Math.min(y0, y1);\n",
  14340. " var width = Math.abs(x1 - x0);\n",
  14341. " var height = Math.abs(y1 - y0);\n",
  14342. "\n",
  14343. " fig.rubberband_context.clearRect(\n",
  14344. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  14345. "\n",
  14346. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  14347. "}\n",
  14348. "\n",
  14349. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  14350. " // Updates the figure title.\n",
  14351. " fig.header.textContent = msg['label'];\n",
  14352. "}\n",
  14353. "\n",
  14354. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  14355. " var cursor = msg['cursor'];\n",
  14356. " switch(cursor)\n",
  14357. " {\n",
  14358. " case 0:\n",
  14359. " cursor = 'pointer';\n",
  14360. " break;\n",
  14361. " case 1:\n",
  14362. " cursor = 'default';\n",
  14363. " break;\n",
  14364. " case 2:\n",
  14365. " cursor = 'crosshair';\n",
  14366. " break;\n",
  14367. " case 3:\n",
  14368. " cursor = 'move';\n",
  14369. " break;\n",
  14370. " }\n",
  14371. " fig.rubberband_canvas.style.cursor = cursor;\n",
  14372. "}\n",
  14373. "\n",
  14374. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  14375. " fig.message.textContent = msg['message'];\n",
  14376. "}\n",
  14377. "\n",
  14378. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  14379. " // Request the server to send over a new figure.\n",
  14380. " fig.send_draw_message();\n",
  14381. "}\n",
  14382. "\n",
  14383. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  14384. " fig.image_mode = msg['mode'];\n",
  14385. "}\n",
  14386. "\n",
  14387. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  14388. " // Called whenever the canvas gets updated.\n",
  14389. " this.send_message(\"ack\", {});\n",
  14390. "}\n",
  14391. "\n",
  14392. "// A function to construct a web socket function for onmessage handling.\n",
  14393. "// Called in the figure constructor.\n",
  14394. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  14395. " return function socket_on_message(evt) {\n",
  14396. " if (evt.data instanceof Blob) {\n",
  14397. " /* FIXME: We get \"Resource interpreted as Image but\n",
  14398. " * transferred with MIME type text/plain:\" errors on\n",
  14399. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  14400. " * to be part of the websocket stream */\n",
  14401. " evt.data.type = \"image/png\";\n",
  14402. "\n",
  14403. " /* Free the memory for the previous frames */\n",
  14404. " if (fig.imageObj.src) {\n",
  14405. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  14406. " fig.imageObj.src);\n",
  14407. " }\n",
  14408. "\n",
  14409. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  14410. " evt.data);\n",
  14411. " fig.updated_canvas_event();\n",
  14412. " fig.waiting = false;\n",
  14413. " return;\n",
  14414. " }\n",
  14415. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  14416. " fig.imageObj.src = evt.data;\n",
  14417. " fig.updated_canvas_event();\n",
  14418. " fig.waiting = false;\n",
  14419. " return;\n",
  14420. " }\n",
  14421. "\n",
  14422. " var msg = JSON.parse(evt.data);\n",
  14423. " var msg_type = msg['type'];\n",
  14424. "\n",
  14425. " // Call the \"handle_{type}\" callback, which takes\n",
  14426. " // the figure and JSON message as its only arguments.\n",
  14427. " try {\n",
  14428. " var callback = fig[\"handle_\" + msg_type];\n",
  14429. " } catch (e) {\n",
  14430. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  14431. " return;\n",
  14432. " }\n",
  14433. "\n",
  14434. " if (callback) {\n",
  14435. " try {\n",
  14436. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  14437. " callback(fig, msg);\n",
  14438. " } catch (e) {\n",
  14439. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  14440. " }\n",
  14441. " }\n",
  14442. " };\n",
  14443. "}\n",
  14444. "\n",
  14445. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  14446. "mpl.findpos = function(e) {\n",
  14447. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  14448. " var targ;\n",
  14449. " if (!e)\n",
  14450. " e = window.event;\n",
  14451. " if (e.target)\n",
  14452. " targ = e.target;\n",
  14453. " else if (e.srcElement)\n",
  14454. " targ = e.srcElement;\n",
  14455. " if (targ.nodeType == 3) // defeat Safari bug\n",
  14456. " targ = targ.parentNode;\n",
  14457. "\n",
  14458. " // jQuery normalizes the pageX and pageY\n",
  14459. " // pageX,Y are the mouse positions relative to the document\n",
  14460. " // offset() returns the position of the element relative to the document\n",
  14461. " var x = e.pageX - $(targ).offset().left;\n",
  14462. " var y = e.pageY - $(targ).offset().top;\n",
  14463. "\n",
  14464. " return {\"x\": x, \"y\": y};\n",
  14465. "};\n",
  14466. "\n",
  14467. "/*\n",
  14468. " * return a copy of an object with only non-object keys\n",
  14469. " * we need this to avoid circular references\n",
  14470. " * http://stackoverflow.com/a/24161582/3208463\n",
  14471. " */\n",
  14472. "function simpleKeys (original) {\n",
  14473. " return Object.keys(original).reduce(function (obj, key) {\n",
  14474. " if (typeof original[key] !== 'object')\n",
  14475. " obj[key] = original[key]\n",
  14476. " return obj;\n",
  14477. " }, {});\n",
  14478. "}\n",
  14479. "\n",
  14480. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  14481. " var canvas_pos = mpl.findpos(event)\n",
  14482. "\n",
  14483. " if (name === 'button_press')\n",
  14484. " {\n",
  14485. " this.canvas.focus();\n",
  14486. " this.canvas_div.focus();\n",
  14487. " }\n",
  14488. "\n",
  14489. " var x = canvas_pos.x * mpl.ratio;\n",
  14490. " var y = canvas_pos.y * mpl.ratio;\n",
  14491. "\n",
  14492. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  14493. " step: event.step,\n",
  14494. " guiEvent: simpleKeys(event)});\n",
  14495. "\n",
  14496. " /* This prevents the web browser from automatically changing to\n",
  14497. " * the text insertion cursor when the button is pressed. We want\n",
  14498. " * to control all of the cursor setting manually through the\n",
  14499. " * 'cursor' event from matplotlib */\n",
  14500. " event.preventDefault();\n",
  14501. " return false;\n",
  14502. "}\n",
  14503. "\n",
  14504. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  14505. " // Handle any extra behaviour associated with a key event\n",
  14506. "}\n",
  14507. "\n",
  14508. "mpl.figure.prototype.key_event = function(event, name) {\n",
  14509. "\n",
  14510. " // Prevent repeat events\n",
  14511. " if (name == 'key_press')\n",
  14512. " {\n",
  14513. " if (event.which === this._key)\n",
  14514. " return;\n",
  14515. " else\n",
  14516. " this._key = event.which;\n",
  14517. " }\n",
  14518. " if (name == 'key_release')\n",
  14519. " this._key = null;\n",
  14520. "\n",
  14521. " var value = '';\n",
  14522. " if (event.ctrlKey && event.which != 17)\n",
  14523. " value += \"ctrl+\";\n",
  14524. " if (event.altKey && event.which != 18)\n",
  14525. " value += \"alt+\";\n",
  14526. " if (event.shiftKey && event.which != 16)\n",
  14527. " value += \"shift+\";\n",
  14528. "\n",
  14529. " value += 'k';\n",
  14530. " value += event.which.toString();\n",
  14531. "\n",
  14532. " this._key_event_extra(event, name);\n",
  14533. "\n",
  14534. " this.send_message(name, {key: value,\n",
  14535. " guiEvent: simpleKeys(event)});\n",
  14536. " return false;\n",
  14537. "}\n",
  14538. "\n",
  14539. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  14540. " if (name == 'download') {\n",
  14541. " this.handle_save(this, null);\n",
  14542. " } else {\n",
  14543. " this.send_message(\"toolbar_button\", {name: name});\n",
  14544. " }\n",
  14545. "};\n",
  14546. "\n",
  14547. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  14548. " this.message.textContent = tooltip;\n",
  14549. "};\n",
  14550. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  14551. "\n",
  14552. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  14553. "\n",
  14554. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  14555. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  14556. " // object with the appropriate methods. Currently this is a non binary\n",
  14557. " // socket, so there is still some room for performance tuning.\n",
  14558. " var ws = {};\n",
  14559. "\n",
  14560. " ws.close = function() {\n",
  14561. " comm.close()\n",
  14562. " };\n",
  14563. " ws.send = function(m) {\n",
  14564. " //console.log('sending', m);\n",
  14565. " comm.send(m);\n",
  14566. " };\n",
  14567. " // Register the callback with on_msg.\n",
  14568. " comm.on_msg(function(msg) {\n",
  14569. " //console.log('receiving', msg['content']['data'], msg);\n",
  14570. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  14571. " ws.onmessage(msg['content']['data'])\n",
  14572. " });\n",
  14573. " return ws;\n",
  14574. "}\n",
  14575. "\n",
  14576. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  14577. " // This is the function which gets called when the mpl process\n",
  14578. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  14579. "\n",
  14580. " var id = msg.content.data.id;\n",
  14581. " // Get hold of the div created by the display call when the Comm\n",
  14582. " // socket was opened in Python.\n",
  14583. " var element = $(\"#\" + id);\n",
  14584. " var ws_proxy = comm_websocket_adapter(comm)\n",
  14585. "\n",
  14586. " function ondownload(figure, format) {\n",
  14587. " window.open(figure.imageObj.src);\n",
  14588. " }\n",
  14589. "\n",
  14590. " var fig = new mpl.figure(id, ws_proxy,\n",
  14591. " ondownload,\n",
  14592. " element.get(0));\n",
  14593. "\n",
  14594. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  14595. " // web socket which is closed, not our websocket->open comm proxy.\n",
  14596. " ws_proxy.onopen();\n",
  14597. "\n",
  14598. " fig.parent_element = element.get(0);\n",
  14599. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  14600. " if (!fig.cell_info) {\n",
  14601. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  14602. " return;\n",
  14603. " }\n",
  14604. "\n",
  14605. " var output_index = fig.cell_info[2]\n",
  14606. " var cell = fig.cell_info[0];\n",
  14607. "\n",
  14608. "};\n",
  14609. "\n",
  14610. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  14611. " var width = fig.canvas.width/mpl.ratio\n",
  14612. " fig.root.unbind('remove')\n",
  14613. "\n",
  14614. " // Update the output cell to use the data from the current canvas.\n",
  14615. " fig.push_to_output();\n",
  14616. " var dataURL = fig.canvas.toDataURL();\n",
  14617. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  14618. " // the notebook keyboard shortcuts fail.\n",
  14619. " IPython.keyboard_manager.enable()\n",
  14620. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  14621. " fig.close_ws(fig, msg);\n",
  14622. "}\n",
  14623. "\n",
  14624. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  14625. " fig.send_message('closing', msg);\n",
  14626. " // fig.ws.close()\n",
  14627. "}\n",
  14628. "\n",
  14629. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  14630. " // Turn the data on the canvas into data in the output cell.\n",
  14631. " var width = this.canvas.width/mpl.ratio\n",
  14632. " var dataURL = this.canvas.toDataURL();\n",
  14633. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  14634. "}\n",
  14635. "\n",
  14636. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  14637. " // Tell IPython that the notebook contents must change.\n",
  14638. " IPython.notebook.set_dirty(true);\n",
  14639. " this.send_message(\"ack\", {});\n",
  14640. " var fig = this;\n",
  14641. " // Wait a second, then push the new image to the DOM so\n",
  14642. " // that it is saved nicely (might be nice to debounce this).\n",
  14643. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  14644. "}\n",
  14645. "\n",
  14646. "mpl.figure.prototype._init_toolbar = function() {\n",
  14647. " var fig = this;\n",
  14648. "\n",
  14649. " var nav_element = $('<div/>')\n",
  14650. " nav_element.attr('style', 'width: 100%');\n",
  14651. " this.root.append(nav_element);\n",
  14652. "\n",
  14653. " // Define a callback function for later on.\n",
  14654. " function toolbar_event(event) {\n",
  14655. " return fig.toolbar_button_onclick(event['data']);\n",
  14656. " }\n",
  14657. " function toolbar_mouse_event(event) {\n",
  14658. " return fig.toolbar_button_onmouseover(event['data']);\n",
  14659. " }\n",
  14660. "\n",
  14661. " for(var toolbar_ind in mpl.toolbar_items){\n",
  14662. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  14663. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  14664. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  14665. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  14666. "\n",
  14667. " if (!name) { continue; };\n",
  14668. "\n",
  14669. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  14670. " button.click(method_name, toolbar_event);\n",
  14671. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  14672. " nav_element.append(button);\n",
  14673. " }\n",
  14674. "\n",
  14675. " // Add the status bar.\n",
  14676. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  14677. " nav_element.append(status_bar);\n",
  14678. " this.message = status_bar[0];\n",
  14679. "\n",
  14680. " // Add the close button to the window.\n",
  14681. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  14682. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  14683. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  14684. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  14685. " buttongrp.append(button);\n",
  14686. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  14687. " titlebar.prepend(buttongrp);\n",
  14688. "}\n",
  14689. "\n",
  14690. "mpl.figure.prototype._root_extra_style = function(el){\n",
  14691. " var fig = this\n",
  14692. " el.on(\"remove\", function(){\n",
  14693. "\tfig.close_ws(fig, {});\n",
  14694. " });\n",
  14695. "}\n",
  14696. "\n",
  14697. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  14698. " // this is important to make the div 'focusable\n",
  14699. " el.attr('tabindex', 0)\n",
  14700. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  14701. " // off when our div gets focus\n",
  14702. "\n",
  14703. " // location in version 3\n",
  14704. " if (IPython.notebook.keyboard_manager) {\n",
  14705. " IPython.notebook.keyboard_manager.register_events(el);\n",
  14706. " }\n",
  14707. " else {\n",
  14708. " // location in version 2\n",
  14709. " IPython.keyboard_manager.register_events(el);\n",
  14710. " }\n",
  14711. "\n",
  14712. "}\n",
  14713. "\n",
  14714. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  14715. " var manager = IPython.notebook.keyboard_manager;\n",
  14716. " if (!manager)\n",
  14717. " manager = IPython.keyboard_manager;\n",
  14718. "\n",
  14719. " // Check for shift+enter\n",
  14720. " if (event.shiftKey && event.which == 13) {\n",
  14721. " this.canvas_div.blur();\n",
  14722. " event.shiftKey = false;\n",
  14723. " // Send a \"J\" for go to next cell\n",
  14724. " event.which = 74;\n",
  14725. " event.keyCode = 74;\n",
  14726. " manager.command_mode();\n",
  14727. " manager.handle_keydown(event);\n",
  14728. " }\n",
  14729. "}\n",
  14730. "\n",
  14731. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  14732. " fig.ondownload(fig, null);\n",
  14733. "}\n",
  14734. "\n",
  14735. "\n",
  14736. "mpl.find_output_cell = function(html_output) {\n",
  14737. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  14738. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  14739. " // IPython event is triggered only after the cells have been serialised, which for\n",
  14740. " // our purposes (turning an active figure into a static one), is too late.\n",
  14741. " var cells = IPython.notebook.get_cells();\n",
  14742. " var ncells = cells.length;\n",
  14743. " for (var i=0; i<ncells; i++) {\n",
  14744. " var cell = cells[i];\n",
  14745. " if (cell.cell_type === 'code'){\n",
  14746. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  14747. " var data = cell.output_area.outputs[j];\n",
  14748. " if (data.data) {\n",
  14749. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  14750. " data = data.data;\n",
  14751. " }\n",
  14752. " if (data['text/html'] == html_output) {\n",
  14753. " return [cell, data, j];\n",
  14754. " }\n",
  14755. " }\n",
  14756. " }\n",
  14757. " }\n",
  14758. "}\n",
  14759. "\n",
  14760. "// Register the function which deals with the matplotlib target/channel.\n",
  14761. "// The kernel may be null if the page has been refreshed.\n",
  14762. "if (IPython.notebook.kernel != null) {\n",
  14763. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  14764. "}\n"
  14765. ],
  14766. "text/plain": [
  14767. "<IPython.core.display.Javascript object>"
  14768. ]
  14769. },
  14770. "metadata": {},
  14771. "output_type": "display_data"
  14772. },
  14773. {
  14774. "data": {
  14775. "text/html": [
  14776. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  14777. ],
  14778. "text/plain": [
  14779. "<IPython.core.display.HTML object>"
  14780. ]
  14781. },
  14782. "metadata": {},
  14783. "output_type": "display_data"
  14784. },
  14785. {
  14786. "name": "stdout",
  14787. "output_type": "stream",
  14788. "text": [
  14789. "-0.20158166 4.0491223\n",
  14790. "19594.232\n",
  14791. "(243, 203)\n",
  14792. "\n"
  14793. ]
  14794. },
  14795. {
  14796. "data": {
  14797. "application/javascript": [
  14798. "/* Put everything inside the global mpl namespace */\n",
  14799. "window.mpl = {};\n",
  14800. "\n",
  14801. "\n",
  14802. "mpl.get_websocket_type = function() {\n",
  14803. " if (typeof(WebSocket) !== 'undefined') {\n",
  14804. " return WebSocket;\n",
  14805. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  14806. " return MozWebSocket;\n",
  14807. " } else {\n",
  14808. " alert('Your browser does not have WebSocket support.' +\n",
  14809. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  14810. " 'Firefox 4 and 5 are also supported but you ' +\n",
  14811. " 'have to enable WebSockets in about:config.');\n",
  14812. " };\n",
  14813. "}\n",
  14814. "\n",
  14815. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  14816. " this.id = figure_id;\n",
  14817. "\n",
  14818. " this.ws = websocket;\n",
  14819. "\n",
  14820. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  14821. "\n",
  14822. " if (!this.supports_binary) {\n",
  14823. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  14824. " if (warnings) {\n",
  14825. " warnings.style.display = 'block';\n",
  14826. " warnings.textContent = (\n",
  14827. " \"This browser does not support binary websocket messages. \" +\n",
  14828. " \"Performance may be slow.\");\n",
  14829. " }\n",
  14830. " }\n",
  14831. "\n",
  14832. " this.imageObj = new Image();\n",
  14833. "\n",
  14834. " this.context = undefined;\n",
  14835. " this.message = undefined;\n",
  14836. " this.canvas = undefined;\n",
  14837. " this.rubberband_canvas = undefined;\n",
  14838. " this.rubberband_context = undefined;\n",
  14839. " this.format_dropdown = undefined;\n",
  14840. "\n",
  14841. " this.image_mode = 'full';\n",
  14842. "\n",
  14843. " this.root = $('<div/>');\n",
  14844. " this._root_extra_style(this.root)\n",
  14845. " this.root.attr('style', 'display: inline-block');\n",
  14846. "\n",
  14847. " $(parent_element).append(this.root);\n",
  14848. "\n",
  14849. " this._init_header(this);\n",
  14850. " this._init_canvas(this);\n",
  14851. " this._init_toolbar(this);\n",
  14852. "\n",
  14853. " var fig = this;\n",
  14854. "\n",
  14855. " this.waiting = false;\n",
  14856. "\n",
  14857. " this.ws.onopen = function () {\n",
  14858. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  14859. " fig.send_message(\"send_image_mode\", {});\n",
  14860. " if (mpl.ratio != 1) {\n",
  14861. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  14862. " }\n",
  14863. " fig.send_message(\"refresh\", {});\n",
  14864. " }\n",
  14865. "\n",
  14866. " this.imageObj.onload = function() {\n",
  14867. " if (fig.image_mode == 'full') {\n",
  14868. " // Full images could contain transparency (where diff images\n",
  14869. " // almost always do), so we need to clear the canvas so that\n",
  14870. " // there is no ghosting.\n",
  14871. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  14872. " }\n",
  14873. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  14874. " };\n",
  14875. "\n",
  14876. " this.imageObj.onunload = function() {\n",
  14877. " fig.ws.close();\n",
  14878. " }\n",
  14879. "\n",
  14880. " this.ws.onmessage = this._make_on_message_function(this);\n",
  14881. "\n",
  14882. " this.ondownload = ondownload;\n",
  14883. "}\n",
  14884. "\n",
  14885. "mpl.figure.prototype._init_header = function() {\n",
  14886. " var titlebar = $(\n",
  14887. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  14888. " 'ui-helper-clearfix\"/>');\n",
  14889. " var titletext = $(\n",
  14890. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  14891. " 'text-align: center; padding: 3px;\"/>');\n",
  14892. " titlebar.append(titletext)\n",
  14893. " this.root.append(titlebar);\n",
  14894. " this.header = titletext[0];\n",
  14895. "}\n",
  14896. "\n",
  14897. "\n",
  14898. "\n",
  14899. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  14900. "\n",
  14901. "}\n",
  14902. "\n",
  14903. "\n",
  14904. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  14905. "\n",
  14906. "}\n",
  14907. "\n",
  14908. "mpl.figure.prototype._init_canvas = function() {\n",
  14909. " var fig = this;\n",
  14910. "\n",
  14911. " var canvas_div = $('<div/>');\n",
  14912. "\n",
  14913. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  14914. "\n",
  14915. " function canvas_keyboard_event(event) {\n",
  14916. " return fig.key_event(event, event['data']);\n",
  14917. " }\n",
  14918. "\n",
  14919. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  14920. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  14921. " this.canvas_div = canvas_div\n",
  14922. " this._canvas_extra_style(canvas_div)\n",
  14923. " this.root.append(canvas_div);\n",
  14924. "\n",
  14925. " var canvas = $('<canvas/>');\n",
  14926. " canvas.addClass('mpl-canvas');\n",
  14927. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  14928. "\n",
  14929. " this.canvas = canvas[0];\n",
  14930. " this.context = canvas[0].getContext(\"2d\");\n",
  14931. "\n",
  14932. " var backingStore = this.context.backingStorePixelRatio ||\n",
  14933. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  14934. "\tthis.context.mozBackingStorePixelRatio ||\n",
  14935. "\tthis.context.msBackingStorePixelRatio ||\n",
  14936. "\tthis.context.oBackingStorePixelRatio ||\n",
  14937. "\tthis.context.backingStorePixelRatio || 1;\n",
  14938. "\n",
  14939. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  14940. "\n",
  14941. " var rubberband = $('<canvas/>');\n",
  14942. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  14943. "\n",
  14944. " var pass_mouse_events = true;\n",
  14945. "\n",
  14946. " canvas_div.resizable({\n",
  14947. " start: function(event, ui) {\n",
  14948. " pass_mouse_events = false;\n",
  14949. " },\n",
  14950. " resize: function(event, ui) {\n",
  14951. " fig.request_resize(ui.size.width, ui.size.height);\n",
  14952. " },\n",
  14953. " stop: function(event, ui) {\n",
  14954. " pass_mouse_events = true;\n",
  14955. " fig.request_resize(ui.size.width, ui.size.height);\n",
  14956. " },\n",
  14957. " });\n",
  14958. "\n",
  14959. " function mouse_event_fn(event) {\n",
  14960. " if (pass_mouse_events)\n",
  14961. " return fig.mouse_event(event, event['data']);\n",
  14962. " }\n",
  14963. "\n",
  14964. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  14965. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  14966. " // Throttle sequential mouse events to 1 every 20ms.\n",
  14967. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  14968. "\n",
  14969. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  14970. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  14971. "\n",
  14972. " canvas_div.on(\"wheel\", function (event) {\n",
  14973. " event = event.originalEvent;\n",
  14974. " event['data'] = 'scroll'\n",
  14975. " if (event.deltaY < 0) {\n",
  14976. " event.step = 1;\n",
  14977. " } else {\n",
  14978. " event.step = -1;\n",
  14979. " }\n",
  14980. " mouse_event_fn(event);\n",
  14981. " });\n",
  14982. "\n",
  14983. " canvas_div.append(canvas);\n",
  14984. " canvas_div.append(rubberband);\n",
  14985. "\n",
  14986. " this.rubberband = rubberband;\n",
  14987. " this.rubberband_canvas = rubberband[0];\n",
  14988. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  14989. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  14990. "\n",
  14991. " this._resize_canvas = function(width, height) {\n",
  14992. " // Keep the size of the canvas, canvas container, and rubber band\n",
  14993. " // canvas in synch.\n",
  14994. " canvas_div.css('width', width)\n",
  14995. " canvas_div.css('height', height)\n",
  14996. "\n",
  14997. " canvas.attr('width', width * mpl.ratio);\n",
  14998. " canvas.attr('height', height * mpl.ratio);\n",
  14999. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  15000. "\n",
  15001. " rubberband.attr('width', width);\n",
  15002. " rubberband.attr('height', height);\n",
  15003. " }\n",
  15004. "\n",
  15005. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  15006. " // upon first draw.\n",
  15007. " this._resize_canvas(600, 600);\n",
  15008. "\n",
  15009. " // Disable right mouse context menu.\n",
  15010. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  15011. " return false;\n",
  15012. " });\n",
  15013. "\n",
  15014. " function set_focus () {\n",
  15015. " canvas.focus();\n",
  15016. " canvas_div.focus();\n",
  15017. " }\n",
  15018. "\n",
  15019. " window.setTimeout(set_focus, 100);\n",
  15020. "}\n",
  15021. "\n",
  15022. "mpl.figure.prototype._init_toolbar = function() {\n",
  15023. " var fig = this;\n",
  15024. "\n",
  15025. " var nav_element = $('<div/>')\n",
  15026. " nav_element.attr('style', 'width: 100%');\n",
  15027. " this.root.append(nav_element);\n",
  15028. "\n",
  15029. " // Define a callback function for later on.\n",
  15030. " function toolbar_event(event) {\n",
  15031. " return fig.toolbar_button_onclick(event['data']);\n",
  15032. " }\n",
  15033. " function toolbar_mouse_event(event) {\n",
  15034. " return fig.toolbar_button_onmouseover(event['data']);\n",
  15035. " }\n",
  15036. "\n",
  15037. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  15038. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  15039. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  15040. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  15041. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  15042. "\n",
  15043. " if (!name) {\n",
  15044. " // put a spacer in here.\n",
  15045. " continue;\n",
  15046. " }\n",
  15047. " var button = $('<button/>');\n",
  15048. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  15049. " 'ui-button-icon-only');\n",
  15050. " button.attr('role', 'button');\n",
  15051. " button.attr('aria-disabled', 'false');\n",
  15052. " button.click(method_name, toolbar_event);\n",
  15053. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  15054. "\n",
  15055. " var icon_img = $('<span/>');\n",
  15056. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  15057. " icon_img.addClass(image);\n",
  15058. " icon_img.addClass('ui-corner-all');\n",
  15059. "\n",
  15060. " var tooltip_span = $('<span/>');\n",
  15061. " tooltip_span.addClass('ui-button-text');\n",
  15062. " tooltip_span.html(tooltip);\n",
  15063. "\n",
  15064. " button.append(icon_img);\n",
  15065. " button.append(tooltip_span);\n",
  15066. "\n",
  15067. " nav_element.append(button);\n",
  15068. " }\n",
  15069. "\n",
  15070. " var fmt_picker_span = $('<span/>');\n",
  15071. "\n",
  15072. " var fmt_picker = $('<select/>');\n",
  15073. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  15074. " fmt_picker_span.append(fmt_picker);\n",
  15075. " nav_element.append(fmt_picker_span);\n",
  15076. " this.format_dropdown = fmt_picker[0];\n",
  15077. "\n",
  15078. " for (var ind in mpl.extensions) {\n",
  15079. " var fmt = mpl.extensions[ind];\n",
  15080. " var option = $(\n",
  15081. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  15082. " fmt_picker.append(option)\n",
  15083. " }\n",
  15084. "\n",
  15085. " // Add hover states to the ui-buttons\n",
  15086. " $( \".ui-button\" ).hover(\n",
  15087. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  15088. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  15089. " );\n",
  15090. "\n",
  15091. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  15092. " nav_element.append(status_bar);\n",
  15093. " this.message = status_bar[0];\n",
  15094. "}\n",
  15095. "\n",
  15096. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  15097. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  15098. " // which will in turn request a refresh of the image.\n",
  15099. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  15100. "}\n",
  15101. "\n",
  15102. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  15103. " properties['type'] = type;\n",
  15104. " properties['figure_id'] = this.id;\n",
  15105. " this.ws.send(JSON.stringify(properties));\n",
  15106. "}\n",
  15107. "\n",
  15108. "mpl.figure.prototype.send_draw_message = function() {\n",
  15109. " if (!this.waiting) {\n",
  15110. " this.waiting = true;\n",
  15111. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  15112. " }\n",
  15113. "}\n",
  15114. "\n",
  15115. "\n",
  15116. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  15117. " var format_dropdown = fig.format_dropdown;\n",
  15118. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  15119. " fig.ondownload(fig, format);\n",
  15120. "}\n",
  15121. "\n",
  15122. "\n",
  15123. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  15124. " var size = msg['size'];\n",
  15125. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  15126. " fig._resize_canvas(size[0], size[1]);\n",
  15127. " fig.send_message(\"refresh\", {});\n",
  15128. " };\n",
  15129. "}\n",
  15130. "\n",
  15131. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  15132. " var x0 = msg['x0'] / mpl.ratio;\n",
  15133. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  15134. " var x1 = msg['x1'] / mpl.ratio;\n",
  15135. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  15136. " x0 = Math.floor(x0) + 0.5;\n",
  15137. " y0 = Math.floor(y0) + 0.5;\n",
  15138. " x1 = Math.floor(x1) + 0.5;\n",
  15139. " y1 = Math.floor(y1) + 0.5;\n",
  15140. " var min_x = Math.min(x0, x1);\n",
  15141. " var min_y = Math.min(y0, y1);\n",
  15142. " var width = Math.abs(x1 - x0);\n",
  15143. " var height = Math.abs(y1 - y0);\n",
  15144. "\n",
  15145. " fig.rubberband_context.clearRect(\n",
  15146. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  15147. "\n",
  15148. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  15149. "}\n",
  15150. "\n",
  15151. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  15152. " // Updates the figure title.\n",
  15153. " fig.header.textContent = msg['label'];\n",
  15154. "}\n",
  15155. "\n",
  15156. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  15157. " var cursor = msg['cursor'];\n",
  15158. " switch(cursor)\n",
  15159. " {\n",
  15160. " case 0:\n",
  15161. " cursor = 'pointer';\n",
  15162. " break;\n",
  15163. " case 1:\n",
  15164. " cursor = 'default';\n",
  15165. " break;\n",
  15166. " case 2:\n",
  15167. " cursor = 'crosshair';\n",
  15168. " break;\n",
  15169. " case 3:\n",
  15170. " cursor = 'move';\n",
  15171. " break;\n",
  15172. " }\n",
  15173. " fig.rubberband_canvas.style.cursor = cursor;\n",
  15174. "}\n",
  15175. "\n",
  15176. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  15177. " fig.message.textContent = msg['message'];\n",
  15178. "}\n",
  15179. "\n",
  15180. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  15181. " // Request the server to send over a new figure.\n",
  15182. " fig.send_draw_message();\n",
  15183. "}\n",
  15184. "\n",
  15185. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  15186. " fig.image_mode = msg['mode'];\n",
  15187. "}\n",
  15188. "\n",
  15189. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  15190. " // Called whenever the canvas gets updated.\n",
  15191. " this.send_message(\"ack\", {});\n",
  15192. "}\n",
  15193. "\n",
  15194. "// A function to construct a web socket function for onmessage handling.\n",
  15195. "// Called in the figure constructor.\n",
  15196. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  15197. " return function socket_on_message(evt) {\n",
  15198. " if (evt.data instanceof Blob) {\n",
  15199. " /* FIXME: We get \"Resource interpreted as Image but\n",
  15200. " * transferred with MIME type text/plain:\" errors on\n",
  15201. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  15202. " * to be part of the websocket stream */\n",
  15203. " evt.data.type = \"image/png\";\n",
  15204. "\n",
  15205. " /* Free the memory for the previous frames */\n",
  15206. " if (fig.imageObj.src) {\n",
  15207. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  15208. " fig.imageObj.src);\n",
  15209. " }\n",
  15210. "\n",
  15211. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  15212. " evt.data);\n",
  15213. " fig.updated_canvas_event();\n",
  15214. " fig.waiting = false;\n",
  15215. " return;\n",
  15216. " }\n",
  15217. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  15218. " fig.imageObj.src = evt.data;\n",
  15219. " fig.updated_canvas_event();\n",
  15220. " fig.waiting = false;\n",
  15221. " return;\n",
  15222. " }\n",
  15223. "\n",
  15224. " var msg = JSON.parse(evt.data);\n",
  15225. " var msg_type = msg['type'];\n",
  15226. "\n",
  15227. " // Call the \"handle_{type}\" callback, which takes\n",
  15228. " // the figure and JSON message as its only arguments.\n",
  15229. " try {\n",
  15230. " var callback = fig[\"handle_\" + msg_type];\n",
  15231. " } catch (e) {\n",
  15232. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  15233. " return;\n",
  15234. " }\n",
  15235. "\n",
  15236. " if (callback) {\n",
  15237. " try {\n",
  15238. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  15239. " callback(fig, msg);\n",
  15240. " } catch (e) {\n",
  15241. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  15242. " }\n",
  15243. " }\n",
  15244. " };\n",
  15245. "}\n",
  15246. "\n",
  15247. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  15248. "mpl.findpos = function(e) {\n",
  15249. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  15250. " var targ;\n",
  15251. " if (!e)\n",
  15252. " e = window.event;\n",
  15253. " if (e.target)\n",
  15254. " targ = e.target;\n",
  15255. " else if (e.srcElement)\n",
  15256. " targ = e.srcElement;\n",
  15257. " if (targ.nodeType == 3) // defeat Safari bug\n",
  15258. " targ = targ.parentNode;\n",
  15259. "\n",
  15260. " // jQuery normalizes the pageX and pageY\n",
  15261. " // pageX,Y are the mouse positions relative to the document\n",
  15262. " // offset() returns the position of the element relative to the document\n",
  15263. " var x = e.pageX - $(targ).offset().left;\n",
  15264. " var y = e.pageY - $(targ).offset().top;\n",
  15265. "\n",
  15266. " return {\"x\": x, \"y\": y};\n",
  15267. "};\n",
  15268. "\n",
  15269. "/*\n",
  15270. " * return a copy of an object with only non-object keys\n",
  15271. " * we need this to avoid circular references\n",
  15272. " * http://stackoverflow.com/a/24161582/3208463\n",
  15273. " */\n",
  15274. "function simpleKeys (original) {\n",
  15275. " return Object.keys(original).reduce(function (obj, key) {\n",
  15276. " if (typeof original[key] !== 'object')\n",
  15277. " obj[key] = original[key]\n",
  15278. " return obj;\n",
  15279. " }, {});\n",
  15280. "}\n",
  15281. "\n",
  15282. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  15283. " var canvas_pos = mpl.findpos(event)\n",
  15284. "\n",
  15285. " if (name === 'button_press')\n",
  15286. " {\n",
  15287. " this.canvas.focus();\n",
  15288. " this.canvas_div.focus();\n",
  15289. " }\n",
  15290. "\n",
  15291. " var x = canvas_pos.x * mpl.ratio;\n",
  15292. " var y = canvas_pos.y * mpl.ratio;\n",
  15293. "\n",
  15294. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  15295. " step: event.step,\n",
  15296. " guiEvent: simpleKeys(event)});\n",
  15297. "\n",
  15298. " /* This prevents the web browser from automatically changing to\n",
  15299. " * the text insertion cursor when the button is pressed. We want\n",
  15300. " * to control all of the cursor setting manually through the\n",
  15301. " * 'cursor' event from matplotlib */\n",
  15302. " event.preventDefault();\n",
  15303. " return false;\n",
  15304. "}\n",
  15305. "\n",
  15306. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  15307. " // Handle any extra behaviour associated with a key event\n",
  15308. "}\n",
  15309. "\n",
  15310. "mpl.figure.prototype.key_event = function(event, name) {\n",
  15311. "\n",
  15312. " // Prevent repeat events\n",
  15313. " if (name == 'key_press')\n",
  15314. " {\n",
  15315. " if (event.which === this._key)\n",
  15316. " return;\n",
  15317. " else\n",
  15318. " this._key = event.which;\n",
  15319. " }\n",
  15320. " if (name == 'key_release')\n",
  15321. " this._key = null;\n",
  15322. "\n",
  15323. " var value = '';\n",
  15324. " if (event.ctrlKey && event.which != 17)\n",
  15325. " value += \"ctrl+\";\n",
  15326. " if (event.altKey && event.which != 18)\n",
  15327. " value += \"alt+\";\n",
  15328. " if (event.shiftKey && event.which != 16)\n",
  15329. " value += \"shift+\";\n",
  15330. "\n",
  15331. " value += 'k';\n",
  15332. " value += event.which.toString();\n",
  15333. "\n",
  15334. " this._key_event_extra(event, name);\n",
  15335. "\n",
  15336. " this.send_message(name, {key: value,\n",
  15337. " guiEvent: simpleKeys(event)});\n",
  15338. " return false;\n",
  15339. "}\n",
  15340. "\n",
  15341. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  15342. " if (name == 'download') {\n",
  15343. " this.handle_save(this, null);\n",
  15344. " } else {\n",
  15345. " this.send_message(\"toolbar_button\", {name: name});\n",
  15346. " }\n",
  15347. "};\n",
  15348. "\n",
  15349. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  15350. " this.message.textContent = tooltip;\n",
  15351. "};\n",
  15352. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  15353. "\n",
  15354. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  15355. "\n",
  15356. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  15357. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  15358. " // object with the appropriate methods. Currently this is a non binary\n",
  15359. " // socket, so there is still some room for performance tuning.\n",
  15360. " var ws = {};\n",
  15361. "\n",
  15362. " ws.close = function() {\n",
  15363. " comm.close()\n",
  15364. " };\n",
  15365. " ws.send = function(m) {\n",
  15366. " //console.log('sending', m);\n",
  15367. " comm.send(m);\n",
  15368. " };\n",
  15369. " // Register the callback with on_msg.\n",
  15370. " comm.on_msg(function(msg) {\n",
  15371. " //console.log('receiving', msg['content']['data'], msg);\n",
  15372. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  15373. " ws.onmessage(msg['content']['data'])\n",
  15374. " });\n",
  15375. " return ws;\n",
  15376. "}\n",
  15377. "\n",
  15378. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  15379. " // This is the function which gets called when the mpl process\n",
  15380. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  15381. "\n",
  15382. " var id = msg.content.data.id;\n",
  15383. " // Get hold of the div created by the display call when the Comm\n",
  15384. " // socket was opened in Python.\n",
  15385. " var element = $(\"#\" + id);\n",
  15386. " var ws_proxy = comm_websocket_adapter(comm)\n",
  15387. "\n",
  15388. " function ondownload(figure, format) {\n",
  15389. " window.open(figure.imageObj.src);\n",
  15390. " }\n",
  15391. "\n",
  15392. " var fig = new mpl.figure(id, ws_proxy,\n",
  15393. " ondownload,\n",
  15394. " element.get(0));\n",
  15395. "\n",
  15396. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  15397. " // web socket which is closed, not our websocket->open comm proxy.\n",
  15398. " ws_proxy.onopen();\n",
  15399. "\n",
  15400. " fig.parent_element = element.get(0);\n",
  15401. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  15402. " if (!fig.cell_info) {\n",
  15403. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  15404. " return;\n",
  15405. " }\n",
  15406. "\n",
  15407. " var output_index = fig.cell_info[2]\n",
  15408. " var cell = fig.cell_info[0];\n",
  15409. "\n",
  15410. "};\n",
  15411. "\n",
  15412. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  15413. " var width = fig.canvas.width/mpl.ratio\n",
  15414. " fig.root.unbind('remove')\n",
  15415. "\n",
  15416. " // Update the output cell to use the data from the current canvas.\n",
  15417. " fig.push_to_output();\n",
  15418. " var dataURL = fig.canvas.toDataURL();\n",
  15419. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  15420. " // the notebook keyboard shortcuts fail.\n",
  15421. " IPython.keyboard_manager.enable()\n",
  15422. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  15423. " fig.close_ws(fig, msg);\n",
  15424. "}\n",
  15425. "\n",
  15426. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  15427. " fig.send_message('closing', msg);\n",
  15428. " // fig.ws.close()\n",
  15429. "}\n",
  15430. "\n",
  15431. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  15432. " // Turn the data on the canvas into data in the output cell.\n",
  15433. " var width = this.canvas.width/mpl.ratio\n",
  15434. " var dataURL = this.canvas.toDataURL();\n",
  15435. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  15436. "}\n",
  15437. "\n",
  15438. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  15439. " // Tell IPython that the notebook contents must change.\n",
  15440. " IPython.notebook.set_dirty(true);\n",
  15441. " this.send_message(\"ack\", {});\n",
  15442. " var fig = this;\n",
  15443. " // Wait a second, then push the new image to the DOM so\n",
  15444. " // that it is saved nicely (might be nice to debounce this).\n",
  15445. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  15446. "}\n",
  15447. "\n",
  15448. "mpl.figure.prototype._init_toolbar = function() {\n",
  15449. " var fig = this;\n",
  15450. "\n",
  15451. " var nav_element = $('<div/>')\n",
  15452. " nav_element.attr('style', 'width: 100%');\n",
  15453. " this.root.append(nav_element);\n",
  15454. "\n",
  15455. " // Define a callback function for later on.\n",
  15456. " function toolbar_event(event) {\n",
  15457. " return fig.toolbar_button_onclick(event['data']);\n",
  15458. " }\n",
  15459. " function toolbar_mouse_event(event) {\n",
  15460. " return fig.toolbar_button_onmouseover(event['data']);\n",
  15461. " }\n",
  15462. "\n",
  15463. " for(var toolbar_ind in mpl.toolbar_items){\n",
  15464. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  15465. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  15466. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  15467. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  15468. "\n",
  15469. " if (!name) { continue; };\n",
  15470. "\n",
  15471. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  15472. " button.click(method_name, toolbar_event);\n",
  15473. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  15474. " nav_element.append(button);\n",
  15475. " }\n",
  15476. "\n",
  15477. " // Add the status bar.\n",
  15478. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  15479. " nav_element.append(status_bar);\n",
  15480. " this.message = status_bar[0];\n",
  15481. "\n",
  15482. " // Add the close button to the window.\n",
  15483. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  15484. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  15485. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  15486. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  15487. " buttongrp.append(button);\n",
  15488. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  15489. " titlebar.prepend(buttongrp);\n",
  15490. "}\n",
  15491. "\n",
  15492. "mpl.figure.prototype._root_extra_style = function(el){\n",
  15493. " var fig = this\n",
  15494. " el.on(\"remove\", function(){\n",
  15495. "\tfig.close_ws(fig, {});\n",
  15496. " });\n",
  15497. "}\n",
  15498. "\n",
  15499. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  15500. " // this is important to make the div 'focusable\n",
  15501. " el.attr('tabindex', 0)\n",
  15502. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  15503. " // off when our div gets focus\n",
  15504. "\n",
  15505. " // location in version 3\n",
  15506. " if (IPython.notebook.keyboard_manager) {\n",
  15507. " IPython.notebook.keyboard_manager.register_events(el);\n",
  15508. " }\n",
  15509. " else {\n",
  15510. " // location in version 2\n",
  15511. " IPython.keyboard_manager.register_events(el);\n",
  15512. " }\n",
  15513. "\n",
  15514. "}\n",
  15515. "\n",
  15516. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  15517. " var manager = IPython.notebook.keyboard_manager;\n",
  15518. " if (!manager)\n",
  15519. " manager = IPython.keyboard_manager;\n",
  15520. "\n",
  15521. " // Check for shift+enter\n",
  15522. " if (event.shiftKey && event.which == 13) {\n",
  15523. " this.canvas_div.blur();\n",
  15524. " event.shiftKey = false;\n",
  15525. " // Send a \"J\" for go to next cell\n",
  15526. " event.which = 74;\n",
  15527. " event.keyCode = 74;\n",
  15528. " manager.command_mode();\n",
  15529. " manager.handle_keydown(event);\n",
  15530. " }\n",
  15531. "}\n",
  15532. "\n",
  15533. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  15534. " fig.ondownload(fig, null);\n",
  15535. "}\n",
  15536. "\n",
  15537. "\n",
  15538. "mpl.find_output_cell = function(html_output) {\n",
  15539. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  15540. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  15541. " // IPython event is triggered only after the cells have been serialised, which for\n",
  15542. " // our purposes (turning an active figure into a static one), is too late.\n",
  15543. " var cells = IPython.notebook.get_cells();\n",
  15544. " var ncells = cells.length;\n",
  15545. " for (var i=0; i<ncells; i++) {\n",
  15546. " var cell = cells[i];\n",
  15547. " if (cell.cell_type === 'code'){\n",
  15548. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  15549. " var data = cell.output_area.outputs[j];\n",
  15550. " if (data.data) {\n",
  15551. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  15552. " data = data.data;\n",
  15553. " }\n",
  15554. " if (data['text/html'] == html_output) {\n",
  15555. " return [cell, data, j];\n",
  15556. " }\n",
  15557. " }\n",
  15558. " }\n",
  15559. " }\n",
  15560. "}\n",
  15561. "\n",
  15562. "// Register the function which deals with the matplotlib target/channel.\n",
  15563. "// The kernel may be null if the page has been refreshed.\n",
  15564. "if (IPython.notebook.kernel != null) {\n",
  15565. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  15566. "}\n"
  15567. ],
  15568. "text/plain": [
  15569. "<IPython.core.display.Javascript object>"
  15570. ]
  15571. },
  15572. "metadata": {},
  15573. "output_type": "display_data"
  15574. },
  15575. {
  15576. "data": {
  15577. "text/html": [
  15578. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  15579. ],
  15580. "text/plain": [
  15581. "<IPython.core.display.HTML object>"
  15582. ]
  15583. },
  15584. "metadata": {},
  15585. "output_type": "display_data"
  15586. },
  15587. {
  15588. "name": "stdout",
  15589. "output_type": "stream",
  15590. "text": [
  15591. "0.0 1.0\n",
  15592. "790.0\n",
  15593. "(348, 313)\n",
  15594. "\n"
  15595. ]
  15596. },
  15597. {
  15598. "data": {
  15599. "application/javascript": [
  15600. "/* Put everything inside the global mpl namespace */\n",
  15601. "window.mpl = {};\n",
  15602. "\n",
  15603. "\n",
  15604. "mpl.get_websocket_type = function() {\n",
  15605. " if (typeof(WebSocket) !== 'undefined') {\n",
  15606. " return WebSocket;\n",
  15607. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  15608. " return MozWebSocket;\n",
  15609. " } else {\n",
  15610. " alert('Your browser does not have WebSocket support.' +\n",
  15611. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  15612. " 'Firefox 4 and 5 are also supported but you ' +\n",
  15613. " 'have to enable WebSockets in about:config.');\n",
  15614. " };\n",
  15615. "}\n",
  15616. "\n",
  15617. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  15618. " this.id = figure_id;\n",
  15619. "\n",
  15620. " this.ws = websocket;\n",
  15621. "\n",
  15622. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  15623. "\n",
  15624. " if (!this.supports_binary) {\n",
  15625. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  15626. " if (warnings) {\n",
  15627. " warnings.style.display = 'block';\n",
  15628. " warnings.textContent = (\n",
  15629. " \"This browser does not support binary websocket messages. \" +\n",
  15630. " \"Performance may be slow.\");\n",
  15631. " }\n",
  15632. " }\n",
  15633. "\n",
  15634. " this.imageObj = new Image();\n",
  15635. "\n",
  15636. " this.context = undefined;\n",
  15637. " this.message = undefined;\n",
  15638. " this.canvas = undefined;\n",
  15639. " this.rubberband_canvas = undefined;\n",
  15640. " this.rubberband_context = undefined;\n",
  15641. " this.format_dropdown = undefined;\n",
  15642. "\n",
  15643. " this.image_mode = 'full';\n",
  15644. "\n",
  15645. " this.root = $('<div/>');\n",
  15646. " this._root_extra_style(this.root)\n",
  15647. " this.root.attr('style', 'display: inline-block');\n",
  15648. "\n",
  15649. " $(parent_element).append(this.root);\n",
  15650. "\n",
  15651. " this._init_header(this);\n",
  15652. " this._init_canvas(this);\n",
  15653. " this._init_toolbar(this);\n",
  15654. "\n",
  15655. " var fig = this;\n",
  15656. "\n",
  15657. " this.waiting = false;\n",
  15658. "\n",
  15659. " this.ws.onopen = function () {\n",
  15660. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  15661. " fig.send_message(\"send_image_mode\", {});\n",
  15662. " if (mpl.ratio != 1) {\n",
  15663. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  15664. " }\n",
  15665. " fig.send_message(\"refresh\", {});\n",
  15666. " }\n",
  15667. "\n",
  15668. " this.imageObj.onload = function() {\n",
  15669. " if (fig.image_mode == 'full') {\n",
  15670. " // Full images could contain transparency (where diff images\n",
  15671. " // almost always do), so we need to clear the canvas so that\n",
  15672. " // there is no ghosting.\n",
  15673. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  15674. " }\n",
  15675. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  15676. " };\n",
  15677. "\n",
  15678. " this.imageObj.onunload = function() {\n",
  15679. " fig.ws.close();\n",
  15680. " }\n",
  15681. "\n",
  15682. " this.ws.onmessage = this._make_on_message_function(this);\n",
  15683. "\n",
  15684. " this.ondownload = ondownload;\n",
  15685. "}\n",
  15686. "\n",
  15687. "mpl.figure.prototype._init_header = function() {\n",
  15688. " var titlebar = $(\n",
  15689. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  15690. " 'ui-helper-clearfix\"/>');\n",
  15691. " var titletext = $(\n",
  15692. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  15693. " 'text-align: center; padding: 3px;\"/>');\n",
  15694. " titlebar.append(titletext)\n",
  15695. " this.root.append(titlebar);\n",
  15696. " this.header = titletext[0];\n",
  15697. "}\n",
  15698. "\n",
  15699. "\n",
  15700. "\n",
  15701. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  15702. "\n",
  15703. "}\n",
  15704. "\n",
  15705. "\n",
  15706. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  15707. "\n",
  15708. "}\n",
  15709. "\n",
  15710. "mpl.figure.prototype._init_canvas = function() {\n",
  15711. " var fig = this;\n",
  15712. "\n",
  15713. " var canvas_div = $('<div/>');\n",
  15714. "\n",
  15715. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  15716. "\n",
  15717. " function canvas_keyboard_event(event) {\n",
  15718. " return fig.key_event(event, event['data']);\n",
  15719. " }\n",
  15720. "\n",
  15721. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  15722. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  15723. " this.canvas_div = canvas_div\n",
  15724. " this._canvas_extra_style(canvas_div)\n",
  15725. " this.root.append(canvas_div);\n",
  15726. "\n",
  15727. " var canvas = $('<canvas/>');\n",
  15728. " canvas.addClass('mpl-canvas');\n",
  15729. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  15730. "\n",
  15731. " this.canvas = canvas[0];\n",
  15732. " this.context = canvas[0].getContext(\"2d\");\n",
  15733. "\n",
  15734. " var backingStore = this.context.backingStorePixelRatio ||\n",
  15735. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  15736. "\tthis.context.mozBackingStorePixelRatio ||\n",
  15737. "\tthis.context.msBackingStorePixelRatio ||\n",
  15738. "\tthis.context.oBackingStorePixelRatio ||\n",
  15739. "\tthis.context.backingStorePixelRatio || 1;\n",
  15740. "\n",
  15741. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  15742. "\n",
  15743. " var rubberband = $('<canvas/>');\n",
  15744. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  15745. "\n",
  15746. " var pass_mouse_events = true;\n",
  15747. "\n",
  15748. " canvas_div.resizable({\n",
  15749. " start: function(event, ui) {\n",
  15750. " pass_mouse_events = false;\n",
  15751. " },\n",
  15752. " resize: function(event, ui) {\n",
  15753. " fig.request_resize(ui.size.width, ui.size.height);\n",
  15754. " },\n",
  15755. " stop: function(event, ui) {\n",
  15756. " pass_mouse_events = true;\n",
  15757. " fig.request_resize(ui.size.width, ui.size.height);\n",
  15758. " },\n",
  15759. " });\n",
  15760. "\n",
  15761. " function mouse_event_fn(event) {\n",
  15762. " if (pass_mouse_events)\n",
  15763. " return fig.mouse_event(event, event['data']);\n",
  15764. " }\n",
  15765. "\n",
  15766. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  15767. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  15768. " // Throttle sequential mouse events to 1 every 20ms.\n",
  15769. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  15770. "\n",
  15771. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  15772. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  15773. "\n",
  15774. " canvas_div.on(\"wheel\", function (event) {\n",
  15775. " event = event.originalEvent;\n",
  15776. " event['data'] = 'scroll'\n",
  15777. " if (event.deltaY < 0) {\n",
  15778. " event.step = 1;\n",
  15779. " } else {\n",
  15780. " event.step = -1;\n",
  15781. " }\n",
  15782. " mouse_event_fn(event);\n",
  15783. " });\n",
  15784. "\n",
  15785. " canvas_div.append(canvas);\n",
  15786. " canvas_div.append(rubberband);\n",
  15787. "\n",
  15788. " this.rubberband = rubberband;\n",
  15789. " this.rubberband_canvas = rubberband[0];\n",
  15790. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  15791. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  15792. "\n",
  15793. " this._resize_canvas = function(width, height) {\n",
  15794. " // Keep the size of the canvas, canvas container, and rubber band\n",
  15795. " // canvas in synch.\n",
  15796. " canvas_div.css('width', width)\n",
  15797. " canvas_div.css('height', height)\n",
  15798. "\n",
  15799. " canvas.attr('width', width * mpl.ratio);\n",
  15800. " canvas.attr('height', height * mpl.ratio);\n",
  15801. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  15802. "\n",
  15803. " rubberband.attr('width', width);\n",
  15804. " rubberband.attr('height', height);\n",
  15805. " }\n",
  15806. "\n",
  15807. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  15808. " // upon first draw.\n",
  15809. " this._resize_canvas(600, 600);\n",
  15810. "\n",
  15811. " // Disable right mouse context menu.\n",
  15812. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  15813. " return false;\n",
  15814. " });\n",
  15815. "\n",
  15816. " function set_focus () {\n",
  15817. " canvas.focus();\n",
  15818. " canvas_div.focus();\n",
  15819. " }\n",
  15820. "\n",
  15821. " window.setTimeout(set_focus, 100);\n",
  15822. "}\n",
  15823. "\n",
  15824. "mpl.figure.prototype._init_toolbar = function() {\n",
  15825. " var fig = this;\n",
  15826. "\n",
  15827. " var nav_element = $('<div/>')\n",
  15828. " nav_element.attr('style', 'width: 100%');\n",
  15829. " this.root.append(nav_element);\n",
  15830. "\n",
  15831. " // Define a callback function for later on.\n",
  15832. " function toolbar_event(event) {\n",
  15833. " return fig.toolbar_button_onclick(event['data']);\n",
  15834. " }\n",
  15835. " function toolbar_mouse_event(event) {\n",
  15836. " return fig.toolbar_button_onmouseover(event['data']);\n",
  15837. " }\n",
  15838. "\n",
  15839. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  15840. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  15841. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  15842. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  15843. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  15844. "\n",
  15845. " if (!name) {\n",
  15846. " // put a spacer in here.\n",
  15847. " continue;\n",
  15848. " }\n",
  15849. " var button = $('<button/>');\n",
  15850. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  15851. " 'ui-button-icon-only');\n",
  15852. " button.attr('role', 'button');\n",
  15853. " button.attr('aria-disabled', 'false');\n",
  15854. " button.click(method_name, toolbar_event);\n",
  15855. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  15856. "\n",
  15857. " var icon_img = $('<span/>');\n",
  15858. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  15859. " icon_img.addClass(image);\n",
  15860. " icon_img.addClass('ui-corner-all');\n",
  15861. "\n",
  15862. " var tooltip_span = $('<span/>');\n",
  15863. " tooltip_span.addClass('ui-button-text');\n",
  15864. " tooltip_span.html(tooltip);\n",
  15865. "\n",
  15866. " button.append(icon_img);\n",
  15867. " button.append(tooltip_span);\n",
  15868. "\n",
  15869. " nav_element.append(button);\n",
  15870. " }\n",
  15871. "\n",
  15872. " var fmt_picker_span = $('<span/>');\n",
  15873. "\n",
  15874. " var fmt_picker = $('<select/>');\n",
  15875. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  15876. " fmt_picker_span.append(fmt_picker);\n",
  15877. " nav_element.append(fmt_picker_span);\n",
  15878. " this.format_dropdown = fmt_picker[0];\n",
  15879. "\n",
  15880. " for (var ind in mpl.extensions) {\n",
  15881. " var fmt = mpl.extensions[ind];\n",
  15882. " var option = $(\n",
  15883. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  15884. " fmt_picker.append(option)\n",
  15885. " }\n",
  15886. "\n",
  15887. " // Add hover states to the ui-buttons\n",
  15888. " $( \".ui-button\" ).hover(\n",
  15889. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  15890. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  15891. " );\n",
  15892. "\n",
  15893. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  15894. " nav_element.append(status_bar);\n",
  15895. " this.message = status_bar[0];\n",
  15896. "}\n",
  15897. "\n",
  15898. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  15899. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  15900. " // which will in turn request a refresh of the image.\n",
  15901. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  15902. "}\n",
  15903. "\n",
  15904. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  15905. " properties['type'] = type;\n",
  15906. " properties['figure_id'] = this.id;\n",
  15907. " this.ws.send(JSON.stringify(properties));\n",
  15908. "}\n",
  15909. "\n",
  15910. "mpl.figure.prototype.send_draw_message = function() {\n",
  15911. " if (!this.waiting) {\n",
  15912. " this.waiting = true;\n",
  15913. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  15914. " }\n",
  15915. "}\n",
  15916. "\n",
  15917. "\n",
  15918. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  15919. " var format_dropdown = fig.format_dropdown;\n",
  15920. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  15921. " fig.ondownload(fig, format);\n",
  15922. "}\n",
  15923. "\n",
  15924. "\n",
  15925. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  15926. " var size = msg['size'];\n",
  15927. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  15928. " fig._resize_canvas(size[0], size[1]);\n",
  15929. " fig.send_message(\"refresh\", {});\n",
  15930. " };\n",
  15931. "}\n",
  15932. "\n",
  15933. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  15934. " var x0 = msg['x0'] / mpl.ratio;\n",
  15935. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  15936. " var x1 = msg['x1'] / mpl.ratio;\n",
  15937. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  15938. " x0 = Math.floor(x0) + 0.5;\n",
  15939. " y0 = Math.floor(y0) + 0.5;\n",
  15940. " x1 = Math.floor(x1) + 0.5;\n",
  15941. " y1 = Math.floor(y1) + 0.5;\n",
  15942. " var min_x = Math.min(x0, x1);\n",
  15943. " var min_y = Math.min(y0, y1);\n",
  15944. " var width = Math.abs(x1 - x0);\n",
  15945. " var height = Math.abs(y1 - y0);\n",
  15946. "\n",
  15947. " fig.rubberband_context.clearRect(\n",
  15948. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  15949. "\n",
  15950. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  15951. "}\n",
  15952. "\n",
  15953. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  15954. " // Updates the figure title.\n",
  15955. " fig.header.textContent = msg['label'];\n",
  15956. "}\n",
  15957. "\n",
  15958. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  15959. " var cursor = msg['cursor'];\n",
  15960. " switch(cursor)\n",
  15961. " {\n",
  15962. " case 0:\n",
  15963. " cursor = 'pointer';\n",
  15964. " break;\n",
  15965. " case 1:\n",
  15966. " cursor = 'default';\n",
  15967. " break;\n",
  15968. " case 2:\n",
  15969. " cursor = 'crosshair';\n",
  15970. " break;\n",
  15971. " case 3:\n",
  15972. " cursor = 'move';\n",
  15973. " break;\n",
  15974. " }\n",
  15975. " fig.rubberband_canvas.style.cursor = cursor;\n",
  15976. "}\n",
  15977. "\n",
  15978. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  15979. " fig.message.textContent = msg['message'];\n",
  15980. "}\n",
  15981. "\n",
  15982. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  15983. " // Request the server to send over a new figure.\n",
  15984. " fig.send_draw_message();\n",
  15985. "}\n",
  15986. "\n",
  15987. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  15988. " fig.image_mode = msg['mode'];\n",
  15989. "}\n",
  15990. "\n",
  15991. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  15992. " // Called whenever the canvas gets updated.\n",
  15993. " this.send_message(\"ack\", {});\n",
  15994. "}\n",
  15995. "\n",
  15996. "// A function to construct a web socket function for onmessage handling.\n",
  15997. "// Called in the figure constructor.\n",
  15998. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  15999. " return function socket_on_message(evt) {\n",
  16000. " if (evt.data instanceof Blob) {\n",
  16001. " /* FIXME: We get \"Resource interpreted as Image but\n",
  16002. " * transferred with MIME type text/plain:\" errors on\n",
  16003. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  16004. " * to be part of the websocket stream */\n",
  16005. " evt.data.type = \"image/png\";\n",
  16006. "\n",
  16007. " /* Free the memory for the previous frames */\n",
  16008. " if (fig.imageObj.src) {\n",
  16009. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  16010. " fig.imageObj.src);\n",
  16011. " }\n",
  16012. "\n",
  16013. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  16014. " evt.data);\n",
  16015. " fig.updated_canvas_event();\n",
  16016. " fig.waiting = false;\n",
  16017. " return;\n",
  16018. " }\n",
  16019. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  16020. " fig.imageObj.src = evt.data;\n",
  16021. " fig.updated_canvas_event();\n",
  16022. " fig.waiting = false;\n",
  16023. " return;\n",
  16024. " }\n",
  16025. "\n",
  16026. " var msg = JSON.parse(evt.data);\n",
  16027. " var msg_type = msg['type'];\n",
  16028. "\n",
  16029. " // Call the \"handle_{type}\" callback, which takes\n",
  16030. " // the figure and JSON message as its only arguments.\n",
  16031. " try {\n",
  16032. " var callback = fig[\"handle_\" + msg_type];\n",
  16033. " } catch (e) {\n",
  16034. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  16035. " return;\n",
  16036. " }\n",
  16037. "\n",
  16038. " if (callback) {\n",
  16039. " try {\n",
  16040. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  16041. " callback(fig, msg);\n",
  16042. " } catch (e) {\n",
  16043. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  16044. " }\n",
  16045. " }\n",
  16046. " };\n",
  16047. "}\n",
  16048. "\n",
  16049. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  16050. "mpl.findpos = function(e) {\n",
  16051. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  16052. " var targ;\n",
  16053. " if (!e)\n",
  16054. " e = window.event;\n",
  16055. " if (e.target)\n",
  16056. " targ = e.target;\n",
  16057. " else if (e.srcElement)\n",
  16058. " targ = e.srcElement;\n",
  16059. " if (targ.nodeType == 3) // defeat Safari bug\n",
  16060. " targ = targ.parentNode;\n",
  16061. "\n",
  16062. " // jQuery normalizes the pageX and pageY\n",
  16063. " // pageX,Y are the mouse positions relative to the document\n",
  16064. " // offset() returns the position of the element relative to the document\n",
  16065. " var x = e.pageX - $(targ).offset().left;\n",
  16066. " var y = e.pageY - $(targ).offset().top;\n",
  16067. "\n",
  16068. " return {\"x\": x, \"y\": y};\n",
  16069. "};\n",
  16070. "\n",
  16071. "/*\n",
  16072. " * return a copy of an object with only non-object keys\n",
  16073. " * we need this to avoid circular references\n",
  16074. " * http://stackoverflow.com/a/24161582/3208463\n",
  16075. " */\n",
  16076. "function simpleKeys (original) {\n",
  16077. " return Object.keys(original).reduce(function (obj, key) {\n",
  16078. " if (typeof original[key] !== 'object')\n",
  16079. " obj[key] = original[key]\n",
  16080. " return obj;\n",
  16081. " }, {});\n",
  16082. "}\n",
  16083. "\n",
  16084. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  16085. " var canvas_pos = mpl.findpos(event)\n",
  16086. "\n",
  16087. " if (name === 'button_press')\n",
  16088. " {\n",
  16089. " this.canvas.focus();\n",
  16090. " this.canvas_div.focus();\n",
  16091. " }\n",
  16092. "\n",
  16093. " var x = canvas_pos.x * mpl.ratio;\n",
  16094. " var y = canvas_pos.y * mpl.ratio;\n",
  16095. "\n",
  16096. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  16097. " step: event.step,\n",
  16098. " guiEvent: simpleKeys(event)});\n",
  16099. "\n",
  16100. " /* This prevents the web browser from automatically changing to\n",
  16101. " * the text insertion cursor when the button is pressed. We want\n",
  16102. " * to control all of the cursor setting manually through the\n",
  16103. " * 'cursor' event from matplotlib */\n",
  16104. " event.preventDefault();\n",
  16105. " return false;\n",
  16106. "}\n",
  16107. "\n",
  16108. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  16109. " // Handle any extra behaviour associated with a key event\n",
  16110. "}\n",
  16111. "\n",
  16112. "mpl.figure.prototype.key_event = function(event, name) {\n",
  16113. "\n",
  16114. " // Prevent repeat events\n",
  16115. " if (name == 'key_press')\n",
  16116. " {\n",
  16117. " if (event.which === this._key)\n",
  16118. " return;\n",
  16119. " else\n",
  16120. " this._key = event.which;\n",
  16121. " }\n",
  16122. " if (name == 'key_release')\n",
  16123. " this._key = null;\n",
  16124. "\n",
  16125. " var value = '';\n",
  16126. " if (event.ctrlKey && event.which != 17)\n",
  16127. " value += \"ctrl+\";\n",
  16128. " if (event.altKey && event.which != 18)\n",
  16129. " value += \"alt+\";\n",
  16130. " if (event.shiftKey && event.which != 16)\n",
  16131. " value += \"shift+\";\n",
  16132. "\n",
  16133. " value += 'k';\n",
  16134. " value += event.which.toString();\n",
  16135. "\n",
  16136. " this._key_event_extra(event, name);\n",
  16137. "\n",
  16138. " this.send_message(name, {key: value,\n",
  16139. " guiEvent: simpleKeys(event)});\n",
  16140. " return false;\n",
  16141. "}\n",
  16142. "\n",
  16143. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  16144. " if (name == 'download') {\n",
  16145. " this.handle_save(this, null);\n",
  16146. " } else {\n",
  16147. " this.send_message(\"toolbar_button\", {name: name});\n",
  16148. " }\n",
  16149. "};\n",
  16150. "\n",
  16151. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  16152. " this.message.textContent = tooltip;\n",
  16153. "};\n",
  16154. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  16155. "\n",
  16156. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  16157. "\n",
  16158. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  16159. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  16160. " // object with the appropriate methods. Currently this is a non binary\n",
  16161. " // socket, so there is still some room for performance tuning.\n",
  16162. " var ws = {};\n",
  16163. "\n",
  16164. " ws.close = function() {\n",
  16165. " comm.close()\n",
  16166. " };\n",
  16167. " ws.send = function(m) {\n",
  16168. " //console.log('sending', m);\n",
  16169. " comm.send(m);\n",
  16170. " };\n",
  16171. " // Register the callback with on_msg.\n",
  16172. " comm.on_msg(function(msg) {\n",
  16173. " //console.log('receiving', msg['content']['data'], msg);\n",
  16174. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  16175. " ws.onmessage(msg['content']['data'])\n",
  16176. " });\n",
  16177. " return ws;\n",
  16178. "}\n",
  16179. "\n",
  16180. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  16181. " // This is the function which gets called when the mpl process\n",
  16182. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  16183. "\n",
  16184. " var id = msg.content.data.id;\n",
  16185. " // Get hold of the div created by the display call when the Comm\n",
  16186. " // socket was opened in Python.\n",
  16187. " var element = $(\"#\" + id);\n",
  16188. " var ws_proxy = comm_websocket_adapter(comm)\n",
  16189. "\n",
  16190. " function ondownload(figure, format) {\n",
  16191. " window.open(figure.imageObj.src);\n",
  16192. " }\n",
  16193. "\n",
  16194. " var fig = new mpl.figure(id, ws_proxy,\n",
  16195. " ondownload,\n",
  16196. " element.get(0));\n",
  16197. "\n",
  16198. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  16199. " // web socket which is closed, not our websocket->open comm proxy.\n",
  16200. " ws_proxy.onopen();\n",
  16201. "\n",
  16202. " fig.parent_element = element.get(0);\n",
  16203. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  16204. " if (!fig.cell_info) {\n",
  16205. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  16206. " return;\n",
  16207. " }\n",
  16208. "\n",
  16209. " var output_index = fig.cell_info[2]\n",
  16210. " var cell = fig.cell_info[0];\n",
  16211. "\n",
  16212. "};\n",
  16213. "\n",
  16214. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  16215. " var width = fig.canvas.width/mpl.ratio\n",
  16216. " fig.root.unbind('remove')\n",
  16217. "\n",
  16218. " // Update the output cell to use the data from the current canvas.\n",
  16219. " fig.push_to_output();\n",
  16220. " var dataURL = fig.canvas.toDataURL();\n",
  16221. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  16222. " // the notebook keyboard shortcuts fail.\n",
  16223. " IPython.keyboard_manager.enable()\n",
  16224. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  16225. " fig.close_ws(fig, msg);\n",
  16226. "}\n",
  16227. "\n",
  16228. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  16229. " fig.send_message('closing', msg);\n",
  16230. " // fig.ws.close()\n",
  16231. "}\n",
  16232. "\n",
  16233. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  16234. " // Turn the data on the canvas into data in the output cell.\n",
  16235. " var width = this.canvas.width/mpl.ratio\n",
  16236. " var dataURL = this.canvas.toDataURL();\n",
  16237. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  16238. "}\n",
  16239. "\n",
  16240. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  16241. " // Tell IPython that the notebook contents must change.\n",
  16242. " IPython.notebook.set_dirty(true);\n",
  16243. " this.send_message(\"ack\", {});\n",
  16244. " var fig = this;\n",
  16245. " // Wait a second, then push the new image to the DOM so\n",
  16246. " // that it is saved nicely (might be nice to debounce this).\n",
  16247. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  16248. "}\n",
  16249. "\n",
  16250. "mpl.figure.prototype._init_toolbar = function() {\n",
  16251. " var fig = this;\n",
  16252. "\n",
  16253. " var nav_element = $('<div/>')\n",
  16254. " nav_element.attr('style', 'width: 100%');\n",
  16255. " this.root.append(nav_element);\n",
  16256. "\n",
  16257. " // Define a callback function for later on.\n",
  16258. " function toolbar_event(event) {\n",
  16259. " return fig.toolbar_button_onclick(event['data']);\n",
  16260. " }\n",
  16261. " function toolbar_mouse_event(event) {\n",
  16262. " return fig.toolbar_button_onmouseover(event['data']);\n",
  16263. " }\n",
  16264. "\n",
  16265. " for(var toolbar_ind in mpl.toolbar_items){\n",
  16266. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  16267. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  16268. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  16269. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  16270. "\n",
  16271. " if (!name) { continue; };\n",
  16272. "\n",
  16273. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  16274. " button.click(method_name, toolbar_event);\n",
  16275. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  16276. " nav_element.append(button);\n",
  16277. " }\n",
  16278. "\n",
  16279. " // Add the status bar.\n",
  16280. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  16281. " nav_element.append(status_bar);\n",
  16282. " this.message = status_bar[0];\n",
  16283. "\n",
  16284. " // Add the close button to the window.\n",
  16285. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  16286. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  16287. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  16288. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  16289. " buttongrp.append(button);\n",
  16290. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  16291. " titlebar.prepend(buttongrp);\n",
  16292. "}\n",
  16293. "\n",
  16294. "mpl.figure.prototype._root_extra_style = function(el){\n",
  16295. " var fig = this\n",
  16296. " el.on(\"remove\", function(){\n",
  16297. "\tfig.close_ws(fig, {});\n",
  16298. " });\n",
  16299. "}\n",
  16300. "\n",
  16301. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  16302. " // this is important to make the div 'focusable\n",
  16303. " el.attr('tabindex', 0)\n",
  16304. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  16305. " // off when our div gets focus\n",
  16306. "\n",
  16307. " // location in version 3\n",
  16308. " if (IPython.notebook.keyboard_manager) {\n",
  16309. " IPython.notebook.keyboard_manager.register_events(el);\n",
  16310. " }\n",
  16311. " else {\n",
  16312. " // location in version 2\n",
  16313. " IPython.keyboard_manager.register_events(el);\n",
  16314. " }\n",
  16315. "\n",
  16316. "}\n",
  16317. "\n",
  16318. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  16319. " var manager = IPython.notebook.keyboard_manager;\n",
  16320. " if (!manager)\n",
  16321. " manager = IPython.keyboard_manager;\n",
  16322. "\n",
  16323. " // Check for shift+enter\n",
  16324. " if (event.shiftKey && event.which == 13) {\n",
  16325. " this.canvas_div.blur();\n",
  16326. " event.shiftKey = false;\n",
  16327. " // Send a \"J\" for go to next cell\n",
  16328. " event.which = 74;\n",
  16329. " event.keyCode = 74;\n",
  16330. " manager.command_mode();\n",
  16331. " manager.handle_keydown(event);\n",
  16332. " }\n",
  16333. "}\n",
  16334. "\n",
  16335. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  16336. " fig.ondownload(fig, null);\n",
  16337. "}\n",
  16338. "\n",
  16339. "\n",
  16340. "mpl.find_output_cell = function(html_output) {\n",
  16341. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  16342. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  16343. " // IPython event is triggered only after the cells have been serialised, which for\n",
  16344. " // our purposes (turning an active figure into a static one), is too late.\n",
  16345. " var cells = IPython.notebook.get_cells();\n",
  16346. " var ncells = cells.length;\n",
  16347. " for (var i=0; i<ncells; i++) {\n",
  16348. " var cell = cells[i];\n",
  16349. " if (cell.cell_type === 'code'){\n",
  16350. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  16351. " var data = cell.output_area.outputs[j];\n",
  16352. " if (data.data) {\n",
  16353. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  16354. " data = data.data;\n",
  16355. " }\n",
  16356. " if (data['text/html'] == html_output) {\n",
  16357. " return [cell, data, j];\n",
  16358. " }\n",
  16359. " }\n",
  16360. " }\n",
  16361. " }\n",
  16362. "}\n",
  16363. "\n",
  16364. "// Register the function which deals with the matplotlib target/channel.\n",
  16365. "// The kernel may be null if the page has been refreshed.\n",
  16366. "if (IPython.notebook.kernel != null) {\n",
  16367. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  16368. "}\n"
  16369. ],
  16370. "text/plain": [
  16371. "<IPython.core.display.Javascript object>"
  16372. ]
  16373. },
  16374. "metadata": {},
  16375. "output_type": "display_data"
  16376. },
  16377. {
  16378. "data": {
  16379. "text/html": [
  16380. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  16381. ],
  16382. "text/plain": [
  16383. "<IPython.core.display.HTML object>"
  16384. ]
  16385. },
  16386. "metadata": {},
  16387. "output_type": "display_data"
  16388. },
  16389. {
  16390. "name": "stdout",
  16391. "output_type": "stream",
  16392. "text": [
  16393. "0 1\n",
  16394. "806\n",
  16395. "(349, 312)\n",
  16396. "\n"
  16397. ]
  16398. },
  16399. {
  16400. "data": {
  16401. "application/javascript": [
  16402. "/* Put everything inside the global mpl namespace */\n",
  16403. "window.mpl = {};\n",
  16404. "\n",
  16405. "\n",
  16406. "mpl.get_websocket_type = function() {\n",
  16407. " if (typeof(WebSocket) !== 'undefined') {\n",
  16408. " return WebSocket;\n",
  16409. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  16410. " return MozWebSocket;\n",
  16411. " } else {\n",
  16412. " alert('Your browser does not have WebSocket support.' +\n",
  16413. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  16414. " 'Firefox 4 and 5 are also supported but you ' +\n",
  16415. " 'have to enable WebSockets in about:config.');\n",
  16416. " };\n",
  16417. "}\n",
  16418. "\n",
  16419. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  16420. " this.id = figure_id;\n",
  16421. "\n",
  16422. " this.ws = websocket;\n",
  16423. "\n",
  16424. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  16425. "\n",
  16426. " if (!this.supports_binary) {\n",
  16427. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  16428. " if (warnings) {\n",
  16429. " warnings.style.display = 'block';\n",
  16430. " warnings.textContent = (\n",
  16431. " \"This browser does not support binary websocket messages. \" +\n",
  16432. " \"Performance may be slow.\");\n",
  16433. " }\n",
  16434. " }\n",
  16435. "\n",
  16436. " this.imageObj = new Image();\n",
  16437. "\n",
  16438. " this.context = undefined;\n",
  16439. " this.message = undefined;\n",
  16440. " this.canvas = undefined;\n",
  16441. " this.rubberband_canvas = undefined;\n",
  16442. " this.rubberband_context = undefined;\n",
  16443. " this.format_dropdown = undefined;\n",
  16444. "\n",
  16445. " this.image_mode = 'full';\n",
  16446. "\n",
  16447. " this.root = $('<div/>');\n",
  16448. " this._root_extra_style(this.root)\n",
  16449. " this.root.attr('style', 'display: inline-block');\n",
  16450. "\n",
  16451. " $(parent_element).append(this.root);\n",
  16452. "\n",
  16453. " this._init_header(this);\n",
  16454. " this._init_canvas(this);\n",
  16455. " this._init_toolbar(this);\n",
  16456. "\n",
  16457. " var fig = this;\n",
  16458. "\n",
  16459. " this.waiting = false;\n",
  16460. "\n",
  16461. " this.ws.onopen = function () {\n",
  16462. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  16463. " fig.send_message(\"send_image_mode\", {});\n",
  16464. " if (mpl.ratio != 1) {\n",
  16465. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  16466. " }\n",
  16467. " fig.send_message(\"refresh\", {});\n",
  16468. " }\n",
  16469. "\n",
  16470. " this.imageObj.onload = function() {\n",
  16471. " if (fig.image_mode == 'full') {\n",
  16472. " // Full images could contain transparency (where diff images\n",
  16473. " // almost always do), so we need to clear the canvas so that\n",
  16474. " // there is no ghosting.\n",
  16475. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  16476. " }\n",
  16477. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  16478. " };\n",
  16479. "\n",
  16480. " this.imageObj.onunload = function() {\n",
  16481. " fig.ws.close();\n",
  16482. " }\n",
  16483. "\n",
  16484. " this.ws.onmessage = this._make_on_message_function(this);\n",
  16485. "\n",
  16486. " this.ondownload = ondownload;\n",
  16487. "}\n",
  16488. "\n",
  16489. "mpl.figure.prototype._init_header = function() {\n",
  16490. " var titlebar = $(\n",
  16491. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  16492. " 'ui-helper-clearfix\"/>');\n",
  16493. " var titletext = $(\n",
  16494. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  16495. " 'text-align: center; padding: 3px;\"/>');\n",
  16496. " titlebar.append(titletext)\n",
  16497. " this.root.append(titlebar);\n",
  16498. " this.header = titletext[0];\n",
  16499. "}\n",
  16500. "\n",
  16501. "\n",
  16502. "\n",
  16503. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  16504. "\n",
  16505. "}\n",
  16506. "\n",
  16507. "\n",
  16508. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  16509. "\n",
  16510. "}\n",
  16511. "\n",
  16512. "mpl.figure.prototype._init_canvas = function() {\n",
  16513. " var fig = this;\n",
  16514. "\n",
  16515. " var canvas_div = $('<div/>');\n",
  16516. "\n",
  16517. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  16518. "\n",
  16519. " function canvas_keyboard_event(event) {\n",
  16520. " return fig.key_event(event, event['data']);\n",
  16521. " }\n",
  16522. "\n",
  16523. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  16524. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  16525. " this.canvas_div = canvas_div\n",
  16526. " this._canvas_extra_style(canvas_div)\n",
  16527. " this.root.append(canvas_div);\n",
  16528. "\n",
  16529. " var canvas = $('<canvas/>');\n",
  16530. " canvas.addClass('mpl-canvas');\n",
  16531. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  16532. "\n",
  16533. " this.canvas = canvas[0];\n",
  16534. " this.context = canvas[0].getContext(\"2d\");\n",
  16535. "\n",
  16536. " var backingStore = this.context.backingStorePixelRatio ||\n",
  16537. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  16538. "\tthis.context.mozBackingStorePixelRatio ||\n",
  16539. "\tthis.context.msBackingStorePixelRatio ||\n",
  16540. "\tthis.context.oBackingStorePixelRatio ||\n",
  16541. "\tthis.context.backingStorePixelRatio || 1;\n",
  16542. "\n",
  16543. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  16544. "\n",
  16545. " var rubberband = $('<canvas/>');\n",
  16546. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  16547. "\n",
  16548. " var pass_mouse_events = true;\n",
  16549. "\n",
  16550. " canvas_div.resizable({\n",
  16551. " start: function(event, ui) {\n",
  16552. " pass_mouse_events = false;\n",
  16553. " },\n",
  16554. " resize: function(event, ui) {\n",
  16555. " fig.request_resize(ui.size.width, ui.size.height);\n",
  16556. " },\n",
  16557. " stop: function(event, ui) {\n",
  16558. " pass_mouse_events = true;\n",
  16559. " fig.request_resize(ui.size.width, ui.size.height);\n",
  16560. " },\n",
  16561. " });\n",
  16562. "\n",
  16563. " function mouse_event_fn(event) {\n",
  16564. " if (pass_mouse_events)\n",
  16565. " return fig.mouse_event(event, event['data']);\n",
  16566. " }\n",
  16567. "\n",
  16568. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  16569. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  16570. " // Throttle sequential mouse events to 1 every 20ms.\n",
  16571. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  16572. "\n",
  16573. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  16574. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  16575. "\n",
  16576. " canvas_div.on(\"wheel\", function (event) {\n",
  16577. " event = event.originalEvent;\n",
  16578. " event['data'] = 'scroll'\n",
  16579. " if (event.deltaY < 0) {\n",
  16580. " event.step = 1;\n",
  16581. " } else {\n",
  16582. " event.step = -1;\n",
  16583. " }\n",
  16584. " mouse_event_fn(event);\n",
  16585. " });\n",
  16586. "\n",
  16587. " canvas_div.append(canvas);\n",
  16588. " canvas_div.append(rubberband);\n",
  16589. "\n",
  16590. " this.rubberband = rubberband;\n",
  16591. " this.rubberband_canvas = rubberband[0];\n",
  16592. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  16593. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  16594. "\n",
  16595. " this._resize_canvas = function(width, height) {\n",
  16596. " // Keep the size of the canvas, canvas container, and rubber band\n",
  16597. " // canvas in synch.\n",
  16598. " canvas_div.css('width', width)\n",
  16599. " canvas_div.css('height', height)\n",
  16600. "\n",
  16601. " canvas.attr('width', width * mpl.ratio);\n",
  16602. " canvas.attr('height', height * mpl.ratio);\n",
  16603. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  16604. "\n",
  16605. " rubberband.attr('width', width);\n",
  16606. " rubberband.attr('height', height);\n",
  16607. " }\n",
  16608. "\n",
  16609. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  16610. " // upon first draw.\n",
  16611. " this._resize_canvas(600, 600);\n",
  16612. "\n",
  16613. " // Disable right mouse context menu.\n",
  16614. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  16615. " return false;\n",
  16616. " });\n",
  16617. "\n",
  16618. " function set_focus () {\n",
  16619. " canvas.focus();\n",
  16620. " canvas_div.focus();\n",
  16621. " }\n",
  16622. "\n",
  16623. " window.setTimeout(set_focus, 100);\n",
  16624. "}\n",
  16625. "\n",
  16626. "mpl.figure.prototype._init_toolbar = function() {\n",
  16627. " var fig = this;\n",
  16628. "\n",
  16629. " var nav_element = $('<div/>')\n",
  16630. " nav_element.attr('style', 'width: 100%');\n",
  16631. " this.root.append(nav_element);\n",
  16632. "\n",
  16633. " // Define a callback function for later on.\n",
  16634. " function toolbar_event(event) {\n",
  16635. " return fig.toolbar_button_onclick(event['data']);\n",
  16636. " }\n",
  16637. " function toolbar_mouse_event(event) {\n",
  16638. " return fig.toolbar_button_onmouseover(event['data']);\n",
  16639. " }\n",
  16640. "\n",
  16641. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  16642. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  16643. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  16644. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  16645. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  16646. "\n",
  16647. " if (!name) {\n",
  16648. " // put a spacer in here.\n",
  16649. " continue;\n",
  16650. " }\n",
  16651. " var button = $('<button/>');\n",
  16652. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  16653. " 'ui-button-icon-only');\n",
  16654. " button.attr('role', 'button');\n",
  16655. " button.attr('aria-disabled', 'false');\n",
  16656. " button.click(method_name, toolbar_event);\n",
  16657. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  16658. "\n",
  16659. " var icon_img = $('<span/>');\n",
  16660. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  16661. " icon_img.addClass(image);\n",
  16662. " icon_img.addClass('ui-corner-all');\n",
  16663. "\n",
  16664. " var tooltip_span = $('<span/>');\n",
  16665. " tooltip_span.addClass('ui-button-text');\n",
  16666. " tooltip_span.html(tooltip);\n",
  16667. "\n",
  16668. " button.append(icon_img);\n",
  16669. " button.append(tooltip_span);\n",
  16670. "\n",
  16671. " nav_element.append(button);\n",
  16672. " }\n",
  16673. "\n",
  16674. " var fmt_picker_span = $('<span/>');\n",
  16675. "\n",
  16676. " var fmt_picker = $('<select/>');\n",
  16677. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  16678. " fmt_picker_span.append(fmt_picker);\n",
  16679. " nav_element.append(fmt_picker_span);\n",
  16680. " this.format_dropdown = fmt_picker[0];\n",
  16681. "\n",
  16682. " for (var ind in mpl.extensions) {\n",
  16683. " var fmt = mpl.extensions[ind];\n",
  16684. " var option = $(\n",
  16685. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  16686. " fmt_picker.append(option)\n",
  16687. " }\n",
  16688. "\n",
  16689. " // Add hover states to the ui-buttons\n",
  16690. " $( \".ui-button\" ).hover(\n",
  16691. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  16692. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  16693. " );\n",
  16694. "\n",
  16695. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  16696. " nav_element.append(status_bar);\n",
  16697. " this.message = status_bar[0];\n",
  16698. "}\n",
  16699. "\n",
  16700. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  16701. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  16702. " // which will in turn request a refresh of the image.\n",
  16703. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  16704. "}\n",
  16705. "\n",
  16706. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  16707. " properties['type'] = type;\n",
  16708. " properties['figure_id'] = this.id;\n",
  16709. " this.ws.send(JSON.stringify(properties));\n",
  16710. "}\n",
  16711. "\n",
  16712. "mpl.figure.prototype.send_draw_message = function() {\n",
  16713. " if (!this.waiting) {\n",
  16714. " this.waiting = true;\n",
  16715. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  16716. " }\n",
  16717. "}\n",
  16718. "\n",
  16719. "\n",
  16720. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  16721. " var format_dropdown = fig.format_dropdown;\n",
  16722. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  16723. " fig.ondownload(fig, format);\n",
  16724. "}\n",
  16725. "\n",
  16726. "\n",
  16727. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  16728. " var size = msg['size'];\n",
  16729. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  16730. " fig._resize_canvas(size[0], size[1]);\n",
  16731. " fig.send_message(\"refresh\", {});\n",
  16732. " };\n",
  16733. "}\n",
  16734. "\n",
  16735. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  16736. " var x0 = msg['x0'] / mpl.ratio;\n",
  16737. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  16738. " var x1 = msg['x1'] / mpl.ratio;\n",
  16739. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  16740. " x0 = Math.floor(x0) + 0.5;\n",
  16741. " y0 = Math.floor(y0) + 0.5;\n",
  16742. " x1 = Math.floor(x1) + 0.5;\n",
  16743. " y1 = Math.floor(y1) + 0.5;\n",
  16744. " var min_x = Math.min(x0, x1);\n",
  16745. " var min_y = Math.min(y0, y1);\n",
  16746. " var width = Math.abs(x1 - x0);\n",
  16747. " var height = Math.abs(y1 - y0);\n",
  16748. "\n",
  16749. " fig.rubberband_context.clearRect(\n",
  16750. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  16751. "\n",
  16752. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  16753. "}\n",
  16754. "\n",
  16755. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  16756. " // Updates the figure title.\n",
  16757. " fig.header.textContent = msg['label'];\n",
  16758. "}\n",
  16759. "\n",
  16760. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  16761. " var cursor = msg['cursor'];\n",
  16762. " switch(cursor)\n",
  16763. " {\n",
  16764. " case 0:\n",
  16765. " cursor = 'pointer';\n",
  16766. " break;\n",
  16767. " case 1:\n",
  16768. " cursor = 'default';\n",
  16769. " break;\n",
  16770. " case 2:\n",
  16771. " cursor = 'crosshair';\n",
  16772. " break;\n",
  16773. " case 3:\n",
  16774. " cursor = 'move';\n",
  16775. " break;\n",
  16776. " }\n",
  16777. " fig.rubberband_canvas.style.cursor = cursor;\n",
  16778. "}\n",
  16779. "\n",
  16780. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  16781. " fig.message.textContent = msg['message'];\n",
  16782. "}\n",
  16783. "\n",
  16784. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  16785. " // Request the server to send over a new figure.\n",
  16786. " fig.send_draw_message();\n",
  16787. "}\n",
  16788. "\n",
  16789. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  16790. " fig.image_mode = msg['mode'];\n",
  16791. "}\n",
  16792. "\n",
  16793. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  16794. " // Called whenever the canvas gets updated.\n",
  16795. " this.send_message(\"ack\", {});\n",
  16796. "}\n",
  16797. "\n",
  16798. "// A function to construct a web socket function for onmessage handling.\n",
  16799. "// Called in the figure constructor.\n",
  16800. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  16801. " return function socket_on_message(evt) {\n",
  16802. " if (evt.data instanceof Blob) {\n",
  16803. " /* FIXME: We get \"Resource interpreted as Image but\n",
  16804. " * transferred with MIME type text/plain:\" errors on\n",
  16805. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  16806. " * to be part of the websocket stream */\n",
  16807. " evt.data.type = \"image/png\";\n",
  16808. "\n",
  16809. " /* Free the memory for the previous frames */\n",
  16810. " if (fig.imageObj.src) {\n",
  16811. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  16812. " fig.imageObj.src);\n",
  16813. " }\n",
  16814. "\n",
  16815. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  16816. " evt.data);\n",
  16817. " fig.updated_canvas_event();\n",
  16818. " fig.waiting = false;\n",
  16819. " return;\n",
  16820. " }\n",
  16821. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  16822. " fig.imageObj.src = evt.data;\n",
  16823. " fig.updated_canvas_event();\n",
  16824. " fig.waiting = false;\n",
  16825. " return;\n",
  16826. " }\n",
  16827. "\n",
  16828. " var msg = JSON.parse(evt.data);\n",
  16829. " var msg_type = msg['type'];\n",
  16830. "\n",
  16831. " // Call the \"handle_{type}\" callback, which takes\n",
  16832. " // the figure and JSON message as its only arguments.\n",
  16833. " try {\n",
  16834. " var callback = fig[\"handle_\" + msg_type];\n",
  16835. " } catch (e) {\n",
  16836. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  16837. " return;\n",
  16838. " }\n",
  16839. "\n",
  16840. " if (callback) {\n",
  16841. " try {\n",
  16842. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  16843. " callback(fig, msg);\n",
  16844. " } catch (e) {\n",
  16845. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  16846. " }\n",
  16847. " }\n",
  16848. " };\n",
  16849. "}\n",
  16850. "\n",
  16851. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  16852. "mpl.findpos = function(e) {\n",
  16853. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  16854. " var targ;\n",
  16855. " if (!e)\n",
  16856. " e = window.event;\n",
  16857. " if (e.target)\n",
  16858. " targ = e.target;\n",
  16859. " else if (e.srcElement)\n",
  16860. " targ = e.srcElement;\n",
  16861. " if (targ.nodeType == 3) // defeat Safari bug\n",
  16862. " targ = targ.parentNode;\n",
  16863. "\n",
  16864. " // jQuery normalizes the pageX and pageY\n",
  16865. " // pageX,Y are the mouse positions relative to the document\n",
  16866. " // offset() returns the position of the element relative to the document\n",
  16867. " var x = e.pageX - $(targ).offset().left;\n",
  16868. " var y = e.pageY - $(targ).offset().top;\n",
  16869. "\n",
  16870. " return {\"x\": x, \"y\": y};\n",
  16871. "};\n",
  16872. "\n",
  16873. "/*\n",
  16874. " * return a copy of an object with only non-object keys\n",
  16875. " * we need this to avoid circular references\n",
  16876. " * http://stackoverflow.com/a/24161582/3208463\n",
  16877. " */\n",
  16878. "function simpleKeys (original) {\n",
  16879. " return Object.keys(original).reduce(function (obj, key) {\n",
  16880. " if (typeof original[key] !== 'object')\n",
  16881. " obj[key] = original[key]\n",
  16882. " return obj;\n",
  16883. " }, {});\n",
  16884. "}\n",
  16885. "\n",
  16886. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  16887. " var canvas_pos = mpl.findpos(event)\n",
  16888. "\n",
  16889. " if (name === 'button_press')\n",
  16890. " {\n",
  16891. " this.canvas.focus();\n",
  16892. " this.canvas_div.focus();\n",
  16893. " }\n",
  16894. "\n",
  16895. " var x = canvas_pos.x * mpl.ratio;\n",
  16896. " var y = canvas_pos.y * mpl.ratio;\n",
  16897. "\n",
  16898. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  16899. " step: event.step,\n",
  16900. " guiEvent: simpleKeys(event)});\n",
  16901. "\n",
  16902. " /* This prevents the web browser from automatically changing to\n",
  16903. " * the text insertion cursor when the button is pressed. We want\n",
  16904. " * to control all of the cursor setting manually through the\n",
  16905. " * 'cursor' event from matplotlib */\n",
  16906. " event.preventDefault();\n",
  16907. " return false;\n",
  16908. "}\n",
  16909. "\n",
  16910. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  16911. " // Handle any extra behaviour associated with a key event\n",
  16912. "}\n",
  16913. "\n",
  16914. "mpl.figure.prototype.key_event = function(event, name) {\n",
  16915. "\n",
  16916. " // Prevent repeat events\n",
  16917. " if (name == 'key_press')\n",
  16918. " {\n",
  16919. " if (event.which === this._key)\n",
  16920. " return;\n",
  16921. " else\n",
  16922. " this._key = event.which;\n",
  16923. " }\n",
  16924. " if (name == 'key_release')\n",
  16925. " this._key = null;\n",
  16926. "\n",
  16927. " var value = '';\n",
  16928. " if (event.ctrlKey && event.which != 17)\n",
  16929. " value += \"ctrl+\";\n",
  16930. " if (event.altKey && event.which != 18)\n",
  16931. " value += \"alt+\";\n",
  16932. " if (event.shiftKey && event.which != 16)\n",
  16933. " value += \"shift+\";\n",
  16934. "\n",
  16935. " value += 'k';\n",
  16936. " value += event.which.toString();\n",
  16937. "\n",
  16938. " this._key_event_extra(event, name);\n",
  16939. "\n",
  16940. " this.send_message(name, {key: value,\n",
  16941. " guiEvent: simpleKeys(event)});\n",
  16942. " return false;\n",
  16943. "}\n",
  16944. "\n",
  16945. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  16946. " if (name == 'download') {\n",
  16947. " this.handle_save(this, null);\n",
  16948. " } else {\n",
  16949. " this.send_message(\"toolbar_button\", {name: name});\n",
  16950. " }\n",
  16951. "};\n",
  16952. "\n",
  16953. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  16954. " this.message.textContent = tooltip;\n",
  16955. "};\n",
  16956. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  16957. "\n",
  16958. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  16959. "\n",
  16960. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  16961. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  16962. " // object with the appropriate methods. Currently this is a non binary\n",
  16963. " // socket, so there is still some room for performance tuning.\n",
  16964. " var ws = {};\n",
  16965. "\n",
  16966. " ws.close = function() {\n",
  16967. " comm.close()\n",
  16968. " };\n",
  16969. " ws.send = function(m) {\n",
  16970. " //console.log('sending', m);\n",
  16971. " comm.send(m);\n",
  16972. " };\n",
  16973. " // Register the callback with on_msg.\n",
  16974. " comm.on_msg(function(msg) {\n",
  16975. " //console.log('receiving', msg['content']['data'], msg);\n",
  16976. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  16977. " ws.onmessage(msg['content']['data'])\n",
  16978. " });\n",
  16979. " return ws;\n",
  16980. "}\n",
  16981. "\n",
  16982. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  16983. " // This is the function which gets called when the mpl process\n",
  16984. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  16985. "\n",
  16986. " var id = msg.content.data.id;\n",
  16987. " // Get hold of the div created by the display call when the Comm\n",
  16988. " // socket was opened in Python.\n",
  16989. " var element = $(\"#\" + id);\n",
  16990. " var ws_proxy = comm_websocket_adapter(comm)\n",
  16991. "\n",
  16992. " function ondownload(figure, format) {\n",
  16993. " window.open(figure.imageObj.src);\n",
  16994. " }\n",
  16995. "\n",
  16996. " var fig = new mpl.figure(id, ws_proxy,\n",
  16997. " ondownload,\n",
  16998. " element.get(0));\n",
  16999. "\n",
  17000. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  17001. " // web socket which is closed, not our websocket->open comm proxy.\n",
  17002. " ws_proxy.onopen();\n",
  17003. "\n",
  17004. " fig.parent_element = element.get(0);\n",
  17005. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  17006. " if (!fig.cell_info) {\n",
  17007. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  17008. " return;\n",
  17009. " }\n",
  17010. "\n",
  17011. " var output_index = fig.cell_info[2]\n",
  17012. " var cell = fig.cell_info[0];\n",
  17013. "\n",
  17014. "};\n",
  17015. "\n",
  17016. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  17017. " var width = fig.canvas.width/mpl.ratio\n",
  17018. " fig.root.unbind('remove')\n",
  17019. "\n",
  17020. " // Update the output cell to use the data from the current canvas.\n",
  17021. " fig.push_to_output();\n",
  17022. " var dataURL = fig.canvas.toDataURL();\n",
  17023. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  17024. " // the notebook keyboard shortcuts fail.\n",
  17025. " IPython.keyboard_manager.enable()\n",
  17026. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  17027. " fig.close_ws(fig, msg);\n",
  17028. "}\n",
  17029. "\n",
  17030. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  17031. " fig.send_message('closing', msg);\n",
  17032. " // fig.ws.close()\n",
  17033. "}\n",
  17034. "\n",
  17035. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  17036. " // Turn the data on the canvas into data in the output cell.\n",
  17037. " var width = this.canvas.width/mpl.ratio\n",
  17038. " var dataURL = this.canvas.toDataURL();\n",
  17039. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  17040. "}\n",
  17041. "\n",
  17042. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  17043. " // Tell IPython that the notebook contents must change.\n",
  17044. " IPython.notebook.set_dirty(true);\n",
  17045. " this.send_message(\"ack\", {});\n",
  17046. " var fig = this;\n",
  17047. " // Wait a second, then push the new image to the DOM so\n",
  17048. " // that it is saved nicely (might be nice to debounce this).\n",
  17049. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  17050. "}\n",
  17051. "\n",
  17052. "mpl.figure.prototype._init_toolbar = function() {\n",
  17053. " var fig = this;\n",
  17054. "\n",
  17055. " var nav_element = $('<div/>')\n",
  17056. " nav_element.attr('style', 'width: 100%');\n",
  17057. " this.root.append(nav_element);\n",
  17058. "\n",
  17059. " // Define a callback function for later on.\n",
  17060. " function toolbar_event(event) {\n",
  17061. " return fig.toolbar_button_onclick(event['data']);\n",
  17062. " }\n",
  17063. " function toolbar_mouse_event(event) {\n",
  17064. " return fig.toolbar_button_onmouseover(event['data']);\n",
  17065. " }\n",
  17066. "\n",
  17067. " for(var toolbar_ind in mpl.toolbar_items){\n",
  17068. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  17069. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  17070. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  17071. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  17072. "\n",
  17073. " if (!name) { continue; };\n",
  17074. "\n",
  17075. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  17076. " button.click(method_name, toolbar_event);\n",
  17077. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  17078. " nav_element.append(button);\n",
  17079. " }\n",
  17080. "\n",
  17081. " // Add the status bar.\n",
  17082. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  17083. " nav_element.append(status_bar);\n",
  17084. " this.message = status_bar[0];\n",
  17085. "\n",
  17086. " // Add the close button to the window.\n",
  17087. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  17088. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  17089. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  17090. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  17091. " buttongrp.append(button);\n",
  17092. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  17093. " titlebar.prepend(buttongrp);\n",
  17094. "}\n",
  17095. "\n",
  17096. "mpl.figure.prototype._root_extra_style = function(el){\n",
  17097. " var fig = this\n",
  17098. " el.on(\"remove\", function(){\n",
  17099. "\tfig.close_ws(fig, {});\n",
  17100. " });\n",
  17101. "}\n",
  17102. "\n",
  17103. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  17104. " // this is important to make the div 'focusable\n",
  17105. " el.attr('tabindex', 0)\n",
  17106. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  17107. " // off when our div gets focus\n",
  17108. "\n",
  17109. " // location in version 3\n",
  17110. " if (IPython.notebook.keyboard_manager) {\n",
  17111. " IPython.notebook.keyboard_manager.register_events(el);\n",
  17112. " }\n",
  17113. " else {\n",
  17114. " // location in version 2\n",
  17115. " IPython.keyboard_manager.register_events(el);\n",
  17116. " }\n",
  17117. "\n",
  17118. "}\n",
  17119. "\n",
  17120. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  17121. " var manager = IPython.notebook.keyboard_manager;\n",
  17122. " if (!manager)\n",
  17123. " manager = IPython.keyboard_manager;\n",
  17124. "\n",
  17125. " // Check for shift+enter\n",
  17126. " if (event.shiftKey && event.which == 13) {\n",
  17127. " this.canvas_div.blur();\n",
  17128. " event.shiftKey = false;\n",
  17129. " // Send a \"J\" for go to next cell\n",
  17130. " event.which = 74;\n",
  17131. " event.keyCode = 74;\n",
  17132. " manager.command_mode();\n",
  17133. " manager.handle_keydown(event);\n",
  17134. " }\n",
  17135. "}\n",
  17136. "\n",
  17137. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  17138. " fig.ondownload(fig, null);\n",
  17139. "}\n",
  17140. "\n",
  17141. "\n",
  17142. "mpl.find_output_cell = function(html_output) {\n",
  17143. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  17144. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  17145. " // IPython event is triggered only after the cells have been serialised, which for\n",
  17146. " // our purposes (turning an active figure into a static one), is too late.\n",
  17147. " var cells = IPython.notebook.get_cells();\n",
  17148. " var ncells = cells.length;\n",
  17149. " for (var i=0; i<ncells; i++) {\n",
  17150. " var cell = cells[i];\n",
  17151. " if (cell.cell_type === 'code'){\n",
  17152. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  17153. " var data = cell.output_area.outputs[j];\n",
  17154. " if (data.data) {\n",
  17155. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  17156. " data = data.data;\n",
  17157. " }\n",
  17158. " if (data['text/html'] == html_output) {\n",
  17159. " return [cell, data, j];\n",
  17160. " }\n",
  17161. " }\n",
  17162. " }\n",
  17163. " }\n",
  17164. "}\n",
  17165. "\n",
  17166. "// Register the function which deals with the matplotlib target/channel.\n",
  17167. "// The kernel may be null if the page has been refreshed.\n",
  17168. "if (IPython.notebook.kernel != null) {\n",
  17169. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  17170. "}\n"
  17171. ],
  17172. "text/plain": [
  17173. "<IPython.core.display.Javascript object>"
  17174. ]
  17175. },
  17176. "metadata": {},
  17177. "output_type": "display_data"
  17178. },
  17179. {
  17180. "data": {
  17181. "text/html": [
  17182. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  17183. ],
  17184. "text/plain": [
  17185. "<IPython.core.display.HTML object>"
  17186. ]
  17187. },
  17188. "metadata": {},
  17189. "output_type": "display_data"
  17190. },
  17191. {
  17192. "name": "stdout",
  17193. "output_type": "stream",
  17194. "text": [
  17195. "0.0 0.9999999\n",
  17196. "793.4514\n",
  17197. "(369, 320)\n",
  17198. "\n"
  17199. ]
  17200. },
  17201. {
  17202. "data": {
  17203. "application/javascript": [
  17204. "/* Put everything inside the global mpl namespace */\n",
  17205. "window.mpl = {};\n",
  17206. "\n",
  17207. "\n",
  17208. "mpl.get_websocket_type = function() {\n",
  17209. " if (typeof(WebSocket) !== 'undefined') {\n",
  17210. " return WebSocket;\n",
  17211. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  17212. " return MozWebSocket;\n",
  17213. " } else {\n",
  17214. " alert('Your browser does not have WebSocket support.' +\n",
  17215. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  17216. " 'Firefox 4 and 5 are also supported but you ' +\n",
  17217. " 'have to enable WebSockets in about:config.');\n",
  17218. " };\n",
  17219. "}\n",
  17220. "\n",
  17221. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  17222. " this.id = figure_id;\n",
  17223. "\n",
  17224. " this.ws = websocket;\n",
  17225. "\n",
  17226. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  17227. "\n",
  17228. " if (!this.supports_binary) {\n",
  17229. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  17230. " if (warnings) {\n",
  17231. " warnings.style.display = 'block';\n",
  17232. " warnings.textContent = (\n",
  17233. " \"This browser does not support binary websocket messages. \" +\n",
  17234. " \"Performance may be slow.\");\n",
  17235. " }\n",
  17236. " }\n",
  17237. "\n",
  17238. " this.imageObj = new Image();\n",
  17239. "\n",
  17240. " this.context = undefined;\n",
  17241. " this.message = undefined;\n",
  17242. " this.canvas = undefined;\n",
  17243. " this.rubberband_canvas = undefined;\n",
  17244. " this.rubberband_context = undefined;\n",
  17245. " this.format_dropdown = undefined;\n",
  17246. "\n",
  17247. " this.image_mode = 'full';\n",
  17248. "\n",
  17249. " this.root = $('<div/>');\n",
  17250. " this._root_extra_style(this.root)\n",
  17251. " this.root.attr('style', 'display: inline-block');\n",
  17252. "\n",
  17253. " $(parent_element).append(this.root);\n",
  17254. "\n",
  17255. " this._init_header(this);\n",
  17256. " this._init_canvas(this);\n",
  17257. " this._init_toolbar(this);\n",
  17258. "\n",
  17259. " var fig = this;\n",
  17260. "\n",
  17261. " this.waiting = false;\n",
  17262. "\n",
  17263. " this.ws.onopen = function () {\n",
  17264. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  17265. " fig.send_message(\"send_image_mode\", {});\n",
  17266. " if (mpl.ratio != 1) {\n",
  17267. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  17268. " }\n",
  17269. " fig.send_message(\"refresh\", {});\n",
  17270. " }\n",
  17271. "\n",
  17272. " this.imageObj.onload = function() {\n",
  17273. " if (fig.image_mode == 'full') {\n",
  17274. " // Full images could contain transparency (where diff images\n",
  17275. " // almost always do), so we need to clear the canvas so that\n",
  17276. " // there is no ghosting.\n",
  17277. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  17278. " }\n",
  17279. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  17280. " };\n",
  17281. "\n",
  17282. " this.imageObj.onunload = function() {\n",
  17283. " fig.ws.close();\n",
  17284. " }\n",
  17285. "\n",
  17286. " this.ws.onmessage = this._make_on_message_function(this);\n",
  17287. "\n",
  17288. " this.ondownload = ondownload;\n",
  17289. "}\n",
  17290. "\n",
  17291. "mpl.figure.prototype._init_header = function() {\n",
  17292. " var titlebar = $(\n",
  17293. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  17294. " 'ui-helper-clearfix\"/>');\n",
  17295. " var titletext = $(\n",
  17296. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  17297. " 'text-align: center; padding: 3px;\"/>');\n",
  17298. " titlebar.append(titletext)\n",
  17299. " this.root.append(titlebar);\n",
  17300. " this.header = titletext[0];\n",
  17301. "}\n",
  17302. "\n",
  17303. "\n",
  17304. "\n",
  17305. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  17306. "\n",
  17307. "}\n",
  17308. "\n",
  17309. "\n",
  17310. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  17311. "\n",
  17312. "}\n",
  17313. "\n",
  17314. "mpl.figure.prototype._init_canvas = function() {\n",
  17315. " var fig = this;\n",
  17316. "\n",
  17317. " var canvas_div = $('<div/>');\n",
  17318. "\n",
  17319. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  17320. "\n",
  17321. " function canvas_keyboard_event(event) {\n",
  17322. " return fig.key_event(event, event['data']);\n",
  17323. " }\n",
  17324. "\n",
  17325. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  17326. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  17327. " this.canvas_div = canvas_div\n",
  17328. " this._canvas_extra_style(canvas_div)\n",
  17329. " this.root.append(canvas_div);\n",
  17330. "\n",
  17331. " var canvas = $('<canvas/>');\n",
  17332. " canvas.addClass('mpl-canvas');\n",
  17333. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  17334. "\n",
  17335. " this.canvas = canvas[0];\n",
  17336. " this.context = canvas[0].getContext(\"2d\");\n",
  17337. "\n",
  17338. " var backingStore = this.context.backingStorePixelRatio ||\n",
  17339. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  17340. "\tthis.context.mozBackingStorePixelRatio ||\n",
  17341. "\tthis.context.msBackingStorePixelRatio ||\n",
  17342. "\tthis.context.oBackingStorePixelRatio ||\n",
  17343. "\tthis.context.backingStorePixelRatio || 1;\n",
  17344. "\n",
  17345. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  17346. "\n",
  17347. " var rubberband = $('<canvas/>');\n",
  17348. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  17349. "\n",
  17350. " var pass_mouse_events = true;\n",
  17351. "\n",
  17352. " canvas_div.resizable({\n",
  17353. " start: function(event, ui) {\n",
  17354. " pass_mouse_events = false;\n",
  17355. " },\n",
  17356. " resize: function(event, ui) {\n",
  17357. " fig.request_resize(ui.size.width, ui.size.height);\n",
  17358. " },\n",
  17359. " stop: function(event, ui) {\n",
  17360. " pass_mouse_events = true;\n",
  17361. " fig.request_resize(ui.size.width, ui.size.height);\n",
  17362. " },\n",
  17363. " });\n",
  17364. "\n",
  17365. " function mouse_event_fn(event) {\n",
  17366. " if (pass_mouse_events)\n",
  17367. " return fig.mouse_event(event, event['data']);\n",
  17368. " }\n",
  17369. "\n",
  17370. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  17371. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  17372. " // Throttle sequential mouse events to 1 every 20ms.\n",
  17373. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  17374. "\n",
  17375. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  17376. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  17377. "\n",
  17378. " canvas_div.on(\"wheel\", function (event) {\n",
  17379. " event = event.originalEvent;\n",
  17380. " event['data'] = 'scroll'\n",
  17381. " if (event.deltaY < 0) {\n",
  17382. " event.step = 1;\n",
  17383. " } else {\n",
  17384. " event.step = -1;\n",
  17385. " }\n",
  17386. " mouse_event_fn(event);\n",
  17387. " });\n",
  17388. "\n",
  17389. " canvas_div.append(canvas);\n",
  17390. " canvas_div.append(rubberband);\n",
  17391. "\n",
  17392. " this.rubberband = rubberband;\n",
  17393. " this.rubberband_canvas = rubberband[0];\n",
  17394. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  17395. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  17396. "\n",
  17397. " this._resize_canvas = function(width, height) {\n",
  17398. " // Keep the size of the canvas, canvas container, and rubber band\n",
  17399. " // canvas in synch.\n",
  17400. " canvas_div.css('width', width)\n",
  17401. " canvas_div.css('height', height)\n",
  17402. "\n",
  17403. " canvas.attr('width', width * mpl.ratio);\n",
  17404. " canvas.attr('height', height * mpl.ratio);\n",
  17405. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  17406. "\n",
  17407. " rubberband.attr('width', width);\n",
  17408. " rubberband.attr('height', height);\n",
  17409. " }\n",
  17410. "\n",
  17411. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  17412. " // upon first draw.\n",
  17413. " this._resize_canvas(600, 600);\n",
  17414. "\n",
  17415. " // Disable right mouse context menu.\n",
  17416. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  17417. " return false;\n",
  17418. " });\n",
  17419. "\n",
  17420. " function set_focus () {\n",
  17421. " canvas.focus();\n",
  17422. " canvas_div.focus();\n",
  17423. " }\n",
  17424. "\n",
  17425. " window.setTimeout(set_focus, 100);\n",
  17426. "}\n",
  17427. "\n",
  17428. "mpl.figure.prototype._init_toolbar = function() {\n",
  17429. " var fig = this;\n",
  17430. "\n",
  17431. " var nav_element = $('<div/>')\n",
  17432. " nav_element.attr('style', 'width: 100%');\n",
  17433. " this.root.append(nav_element);\n",
  17434. "\n",
  17435. " // Define a callback function for later on.\n",
  17436. " function toolbar_event(event) {\n",
  17437. " return fig.toolbar_button_onclick(event['data']);\n",
  17438. " }\n",
  17439. " function toolbar_mouse_event(event) {\n",
  17440. " return fig.toolbar_button_onmouseover(event['data']);\n",
  17441. " }\n",
  17442. "\n",
  17443. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  17444. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  17445. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  17446. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  17447. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  17448. "\n",
  17449. " if (!name) {\n",
  17450. " // put a spacer in here.\n",
  17451. " continue;\n",
  17452. " }\n",
  17453. " var button = $('<button/>');\n",
  17454. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  17455. " 'ui-button-icon-only');\n",
  17456. " button.attr('role', 'button');\n",
  17457. " button.attr('aria-disabled', 'false');\n",
  17458. " button.click(method_name, toolbar_event);\n",
  17459. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  17460. "\n",
  17461. " var icon_img = $('<span/>');\n",
  17462. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  17463. " icon_img.addClass(image);\n",
  17464. " icon_img.addClass('ui-corner-all');\n",
  17465. "\n",
  17466. " var tooltip_span = $('<span/>');\n",
  17467. " tooltip_span.addClass('ui-button-text');\n",
  17468. " tooltip_span.html(tooltip);\n",
  17469. "\n",
  17470. " button.append(icon_img);\n",
  17471. " button.append(tooltip_span);\n",
  17472. "\n",
  17473. " nav_element.append(button);\n",
  17474. " }\n",
  17475. "\n",
  17476. " var fmt_picker_span = $('<span/>');\n",
  17477. "\n",
  17478. " var fmt_picker = $('<select/>');\n",
  17479. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  17480. " fmt_picker_span.append(fmt_picker);\n",
  17481. " nav_element.append(fmt_picker_span);\n",
  17482. " this.format_dropdown = fmt_picker[0];\n",
  17483. "\n",
  17484. " for (var ind in mpl.extensions) {\n",
  17485. " var fmt = mpl.extensions[ind];\n",
  17486. " var option = $(\n",
  17487. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  17488. " fmt_picker.append(option)\n",
  17489. " }\n",
  17490. "\n",
  17491. " // Add hover states to the ui-buttons\n",
  17492. " $( \".ui-button\" ).hover(\n",
  17493. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  17494. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  17495. " );\n",
  17496. "\n",
  17497. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  17498. " nav_element.append(status_bar);\n",
  17499. " this.message = status_bar[0];\n",
  17500. "}\n",
  17501. "\n",
  17502. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  17503. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  17504. " // which will in turn request a refresh of the image.\n",
  17505. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  17506. "}\n",
  17507. "\n",
  17508. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  17509. " properties['type'] = type;\n",
  17510. " properties['figure_id'] = this.id;\n",
  17511. " this.ws.send(JSON.stringify(properties));\n",
  17512. "}\n",
  17513. "\n",
  17514. "mpl.figure.prototype.send_draw_message = function() {\n",
  17515. " if (!this.waiting) {\n",
  17516. " this.waiting = true;\n",
  17517. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  17518. " }\n",
  17519. "}\n",
  17520. "\n",
  17521. "\n",
  17522. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  17523. " var format_dropdown = fig.format_dropdown;\n",
  17524. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  17525. " fig.ondownload(fig, format);\n",
  17526. "}\n",
  17527. "\n",
  17528. "\n",
  17529. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  17530. " var size = msg['size'];\n",
  17531. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  17532. " fig._resize_canvas(size[0], size[1]);\n",
  17533. " fig.send_message(\"refresh\", {});\n",
  17534. " };\n",
  17535. "}\n",
  17536. "\n",
  17537. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  17538. " var x0 = msg['x0'] / mpl.ratio;\n",
  17539. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  17540. " var x1 = msg['x1'] / mpl.ratio;\n",
  17541. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  17542. " x0 = Math.floor(x0) + 0.5;\n",
  17543. " y0 = Math.floor(y0) + 0.5;\n",
  17544. " x1 = Math.floor(x1) + 0.5;\n",
  17545. " y1 = Math.floor(y1) + 0.5;\n",
  17546. " var min_x = Math.min(x0, x1);\n",
  17547. " var min_y = Math.min(y0, y1);\n",
  17548. " var width = Math.abs(x1 - x0);\n",
  17549. " var height = Math.abs(y1 - y0);\n",
  17550. "\n",
  17551. " fig.rubberband_context.clearRect(\n",
  17552. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  17553. "\n",
  17554. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  17555. "}\n",
  17556. "\n",
  17557. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  17558. " // Updates the figure title.\n",
  17559. " fig.header.textContent = msg['label'];\n",
  17560. "}\n",
  17561. "\n",
  17562. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  17563. " var cursor = msg['cursor'];\n",
  17564. " switch(cursor)\n",
  17565. " {\n",
  17566. " case 0:\n",
  17567. " cursor = 'pointer';\n",
  17568. " break;\n",
  17569. " case 1:\n",
  17570. " cursor = 'default';\n",
  17571. " break;\n",
  17572. " case 2:\n",
  17573. " cursor = 'crosshair';\n",
  17574. " break;\n",
  17575. " case 3:\n",
  17576. " cursor = 'move';\n",
  17577. " break;\n",
  17578. " }\n",
  17579. " fig.rubberband_canvas.style.cursor = cursor;\n",
  17580. "}\n",
  17581. "\n",
  17582. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  17583. " fig.message.textContent = msg['message'];\n",
  17584. "}\n",
  17585. "\n",
  17586. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  17587. " // Request the server to send over a new figure.\n",
  17588. " fig.send_draw_message();\n",
  17589. "}\n",
  17590. "\n",
  17591. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  17592. " fig.image_mode = msg['mode'];\n",
  17593. "}\n",
  17594. "\n",
  17595. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  17596. " // Called whenever the canvas gets updated.\n",
  17597. " this.send_message(\"ack\", {});\n",
  17598. "}\n",
  17599. "\n",
  17600. "// A function to construct a web socket function for onmessage handling.\n",
  17601. "// Called in the figure constructor.\n",
  17602. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  17603. " return function socket_on_message(evt) {\n",
  17604. " if (evt.data instanceof Blob) {\n",
  17605. " /* FIXME: We get \"Resource interpreted as Image but\n",
  17606. " * transferred with MIME type text/plain:\" errors on\n",
  17607. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  17608. " * to be part of the websocket stream */\n",
  17609. " evt.data.type = \"image/png\";\n",
  17610. "\n",
  17611. " /* Free the memory for the previous frames */\n",
  17612. " if (fig.imageObj.src) {\n",
  17613. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  17614. " fig.imageObj.src);\n",
  17615. " }\n",
  17616. "\n",
  17617. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  17618. " evt.data);\n",
  17619. " fig.updated_canvas_event();\n",
  17620. " fig.waiting = false;\n",
  17621. " return;\n",
  17622. " }\n",
  17623. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  17624. " fig.imageObj.src = evt.data;\n",
  17625. " fig.updated_canvas_event();\n",
  17626. " fig.waiting = false;\n",
  17627. " return;\n",
  17628. " }\n",
  17629. "\n",
  17630. " var msg = JSON.parse(evt.data);\n",
  17631. " var msg_type = msg['type'];\n",
  17632. "\n",
  17633. " // Call the \"handle_{type}\" callback, which takes\n",
  17634. " // the figure and JSON message as its only arguments.\n",
  17635. " try {\n",
  17636. " var callback = fig[\"handle_\" + msg_type];\n",
  17637. " } catch (e) {\n",
  17638. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  17639. " return;\n",
  17640. " }\n",
  17641. "\n",
  17642. " if (callback) {\n",
  17643. " try {\n",
  17644. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  17645. " callback(fig, msg);\n",
  17646. " } catch (e) {\n",
  17647. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  17648. " }\n",
  17649. " }\n",
  17650. " };\n",
  17651. "}\n",
  17652. "\n",
  17653. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  17654. "mpl.findpos = function(e) {\n",
  17655. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  17656. " var targ;\n",
  17657. " if (!e)\n",
  17658. " e = window.event;\n",
  17659. " if (e.target)\n",
  17660. " targ = e.target;\n",
  17661. " else if (e.srcElement)\n",
  17662. " targ = e.srcElement;\n",
  17663. " if (targ.nodeType == 3) // defeat Safari bug\n",
  17664. " targ = targ.parentNode;\n",
  17665. "\n",
  17666. " // jQuery normalizes the pageX and pageY\n",
  17667. " // pageX,Y are the mouse positions relative to the document\n",
  17668. " // offset() returns the position of the element relative to the document\n",
  17669. " var x = e.pageX - $(targ).offset().left;\n",
  17670. " var y = e.pageY - $(targ).offset().top;\n",
  17671. "\n",
  17672. " return {\"x\": x, \"y\": y};\n",
  17673. "};\n",
  17674. "\n",
  17675. "/*\n",
  17676. " * return a copy of an object with only non-object keys\n",
  17677. " * we need this to avoid circular references\n",
  17678. " * http://stackoverflow.com/a/24161582/3208463\n",
  17679. " */\n",
  17680. "function simpleKeys (original) {\n",
  17681. " return Object.keys(original).reduce(function (obj, key) {\n",
  17682. " if (typeof original[key] !== 'object')\n",
  17683. " obj[key] = original[key]\n",
  17684. " return obj;\n",
  17685. " }, {});\n",
  17686. "}\n",
  17687. "\n",
  17688. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  17689. " var canvas_pos = mpl.findpos(event)\n",
  17690. "\n",
  17691. " if (name === 'button_press')\n",
  17692. " {\n",
  17693. " this.canvas.focus();\n",
  17694. " this.canvas_div.focus();\n",
  17695. " }\n",
  17696. "\n",
  17697. " var x = canvas_pos.x * mpl.ratio;\n",
  17698. " var y = canvas_pos.y * mpl.ratio;\n",
  17699. "\n",
  17700. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  17701. " step: event.step,\n",
  17702. " guiEvent: simpleKeys(event)});\n",
  17703. "\n",
  17704. " /* This prevents the web browser from automatically changing to\n",
  17705. " * the text insertion cursor when the button is pressed. We want\n",
  17706. " * to control all of the cursor setting manually through the\n",
  17707. " * 'cursor' event from matplotlib */\n",
  17708. " event.preventDefault();\n",
  17709. " return false;\n",
  17710. "}\n",
  17711. "\n",
  17712. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  17713. " // Handle any extra behaviour associated with a key event\n",
  17714. "}\n",
  17715. "\n",
  17716. "mpl.figure.prototype.key_event = function(event, name) {\n",
  17717. "\n",
  17718. " // Prevent repeat events\n",
  17719. " if (name == 'key_press')\n",
  17720. " {\n",
  17721. " if (event.which === this._key)\n",
  17722. " return;\n",
  17723. " else\n",
  17724. " this._key = event.which;\n",
  17725. " }\n",
  17726. " if (name == 'key_release')\n",
  17727. " this._key = null;\n",
  17728. "\n",
  17729. " var value = '';\n",
  17730. " if (event.ctrlKey && event.which != 17)\n",
  17731. " value += \"ctrl+\";\n",
  17732. " if (event.altKey && event.which != 18)\n",
  17733. " value += \"alt+\";\n",
  17734. " if (event.shiftKey && event.which != 16)\n",
  17735. " value += \"shift+\";\n",
  17736. "\n",
  17737. " value += 'k';\n",
  17738. " value += event.which.toString();\n",
  17739. "\n",
  17740. " this._key_event_extra(event, name);\n",
  17741. "\n",
  17742. " this.send_message(name, {key: value,\n",
  17743. " guiEvent: simpleKeys(event)});\n",
  17744. " return false;\n",
  17745. "}\n",
  17746. "\n",
  17747. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  17748. " if (name == 'download') {\n",
  17749. " this.handle_save(this, null);\n",
  17750. " } else {\n",
  17751. " this.send_message(\"toolbar_button\", {name: name});\n",
  17752. " }\n",
  17753. "};\n",
  17754. "\n",
  17755. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  17756. " this.message.textContent = tooltip;\n",
  17757. "};\n",
  17758. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  17759. "\n",
  17760. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  17761. "\n",
  17762. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  17763. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  17764. " // object with the appropriate methods. Currently this is a non binary\n",
  17765. " // socket, so there is still some room for performance tuning.\n",
  17766. " var ws = {};\n",
  17767. "\n",
  17768. " ws.close = function() {\n",
  17769. " comm.close()\n",
  17770. " };\n",
  17771. " ws.send = function(m) {\n",
  17772. " //console.log('sending', m);\n",
  17773. " comm.send(m);\n",
  17774. " };\n",
  17775. " // Register the callback with on_msg.\n",
  17776. " comm.on_msg(function(msg) {\n",
  17777. " //console.log('receiving', msg['content']['data'], msg);\n",
  17778. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  17779. " ws.onmessage(msg['content']['data'])\n",
  17780. " });\n",
  17781. " return ws;\n",
  17782. "}\n",
  17783. "\n",
  17784. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  17785. " // This is the function which gets called when the mpl process\n",
  17786. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  17787. "\n",
  17788. " var id = msg.content.data.id;\n",
  17789. " // Get hold of the div created by the display call when the Comm\n",
  17790. " // socket was opened in Python.\n",
  17791. " var element = $(\"#\" + id);\n",
  17792. " var ws_proxy = comm_websocket_adapter(comm)\n",
  17793. "\n",
  17794. " function ondownload(figure, format) {\n",
  17795. " window.open(figure.imageObj.src);\n",
  17796. " }\n",
  17797. "\n",
  17798. " var fig = new mpl.figure(id, ws_proxy,\n",
  17799. " ondownload,\n",
  17800. " element.get(0));\n",
  17801. "\n",
  17802. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  17803. " // web socket which is closed, not our websocket->open comm proxy.\n",
  17804. " ws_proxy.onopen();\n",
  17805. "\n",
  17806. " fig.parent_element = element.get(0);\n",
  17807. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  17808. " if (!fig.cell_info) {\n",
  17809. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  17810. " return;\n",
  17811. " }\n",
  17812. "\n",
  17813. " var output_index = fig.cell_info[2]\n",
  17814. " var cell = fig.cell_info[0];\n",
  17815. "\n",
  17816. "};\n",
  17817. "\n",
  17818. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  17819. " var width = fig.canvas.width/mpl.ratio\n",
  17820. " fig.root.unbind('remove')\n",
  17821. "\n",
  17822. " // Update the output cell to use the data from the current canvas.\n",
  17823. " fig.push_to_output();\n",
  17824. " var dataURL = fig.canvas.toDataURL();\n",
  17825. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  17826. " // the notebook keyboard shortcuts fail.\n",
  17827. " IPython.keyboard_manager.enable()\n",
  17828. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  17829. " fig.close_ws(fig, msg);\n",
  17830. "}\n",
  17831. "\n",
  17832. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  17833. " fig.send_message('closing', msg);\n",
  17834. " // fig.ws.close()\n",
  17835. "}\n",
  17836. "\n",
  17837. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  17838. " // Turn the data on the canvas into data in the output cell.\n",
  17839. " var width = this.canvas.width/mpl.ratio\n",
  17840. " var dataURL = this.canvas.toDataURL();\n",
  17841. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  17842. "}\n",
  17843. "\n",
  17844. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  17845. " // Tell IPython that the notebook contents must change.\n",
  17846. " IPython.notebook.set_dirty(true);\n",
  17847. " this.send_message(\"ack\", {});\n",
  17848. " var fig = this;\n",
  17849. " // Wait a second, then push the new image to the DOM so\n",
  17850. " // that it is saved nicely (might be nice to debounce this).\n",
  17851. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  17852. "}\n",
  17853. "\n",
  17854. "mpl.figure.prototype._init_toolbar = function() {\n",
  17855. " var fig = this;\n",
  17856. "\n",
  17857. " var nav_element = $('<div/>')\n",
  17858. " nav_element.attr('style', 'width: 100%');\n",
  17859. " this.root.append(nav_element);\n",
  17860. "\n",
  17861. " // Define a callback function for later on.\n",
  17862. " function toolbar_event(event) {\n",
  17863. " return fig.toolbar_button_onclick(event['data']);\n",
  17864. " }\n",
  17865. " function toolbar_mouse_event(event) {\n",
  17866. " return fig.toolbar_button_onmouseover(event['data']);\n",
  17867. " }\n",
  17868. "\n",
  17869. " for(var toolbar_ind in mpl.toolbar_items){\n",
  17870. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  17871. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  17872. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  17873. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  17874. "\n",
  17875. " if (!name) { continue; };\n",
  17876. "\n",
  17877. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  17878. " button.click(method_name, toolbar_event);\n",
  17879. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  17880. " nav_element.append(button);\n",
  17881. " }\n",
  17882. "\n",
  17883. " // Add the status bar.\n",
  17884. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  17885. " nav_element.append(status_bar);\n",
  17886. " this.message = status_bar[0];\n",
  17887. "\n",
  17888. " // Add the close button to the window.\n",
  17889. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  17890. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  17891. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  17892. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  17893. " buttongrp.append(button);\n",
  17894. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  17895. " titlebar.prepend(buttongrp);\n",
  17896. "}\n",
  17897. "\n",
  17898. "mpl.figure.prototype._root_extra_style = function(el){\n",
  17899. " var fig = this\n",
  17900. " el.on(\"remove\", function(){\n",
  17901. "\tfig.close_ws(fig, {});\n",
  17902. " });\n",
  17903. "}\n",
  17904. "\n",
  17905. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  17906. " // this is important to make the div 'focusable\n",
  17907. " el.attr('tabindex', 0)\n",
  17908. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  17909. " // off when our div gets focus\n",
  17910. "\n",
  17911. " // location in version 3\n",
  17912. " if (IPython.notebook.keyboard_manager) {\n",
  17913. " IPython.notebook.keyboard_manager.register_events(el);\n",
  17914. " }\n",
  17915. " else {\n",
  17916. " // location in version 2\n",
  17917. " IPython.keyboard_manager.register_events(el);\n",
  17918. " }\n",
  17919. "\n",
  17920. "}\n",
  17921. "\n",
  17922. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  17923. " var manager = IPython.notebook.keyboard_manager;\n",
  17924. " if (!manager)\n",
  17925. " manager = IPython.keyboard_manager;\n",
  17926. "\n",
  17927. " // Check for shift+enter\n",
  17928. " if (event.shiftKey && event.which == 13) {\n",
  17929. " this.canvas_div.blur();\n",
  17930. " event.shiftKey = false;\n",
  17931. " // Send a \"J\" for go to next cell\n",
  17932. " event.which = 74;\n",
  17933. " event.keyCode = 74;\n",
  17934. " manager.command_mode();\n",
  17935. " manager.handle_keydown(event);\n",
  17936. " }\n",
  17937. "}\n",
  17938. "\n",
  17939. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  17940. " fig.ondownload(fig, null);\n",
  17941. "}\n",
  17942. "\n",
  17943. "\n",
  17944. "mpl.find_output_cell = function(html_output) {\n",
  17945. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  17946. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  17947. " // IPython event is triggered only after the cells have been serialised, which for\n",
  17948. " // our purposes (turning an active figure into a static one), is too late.\n",
  17949. " var cells = IPython.notebook.get_cells();\n",
  17950. " var ncells = cells.length;\n",
  17951. " for (var i=0; i<ncells; i++) {\n",
  17952. " var cell = cells[i];\n",
  17953. " if (cell.cell_type === 'code'){\n",
  17954. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  17955. " var data = cell.output_area.outputs[j];\n",
  17956. " if (data.data) {\n",
  17957. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  17958. " data = data.data;\n",
  17959. " }\n",
  17960. " if (data['text/html'] == html_output) {\n",
  17961. " return [cell, data, j];\n",
  17962. " }\n",
  17963. " }\n",
  17964. " }\n",
  17965. " }\n",
  17966. "}\n",
  17967. "\n",
  17968. "// Register the function which deals with the matplotlib target/channel.\n",
  17969. "// The kernel may be null if the page has been refreshed.\n",
  17970. "if (IPython.notebook.kernel != null) {\n",
  17971. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  17972. "}\n"
  17973. ],
  17974. "text/plain": [
  17975. "<IPython.core.display.Javascript object>"
  17976. ]
  17977. },
  17978. "metadata": {},
  17979. "output_type": "display_data"
  17980. },
  17981. {
  17982. "data": {
  17983. "text/html": [
  17984. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  17985. ],
  17986. "text/plain": [
  17987. "<IPython.core.display.HTML object>"
  17988. ]
  17989. },
  17990. "metadata": {},
  17991. "output_type": "display_data"
  17992. },
  17993. {
  17994. "name": "stdout",
  17995. "output_type": "stream",
  17996. "text": [
  17997. "-0.212795 3.0631254\n",
  17998. "19324.09\n",
  17999. "(227, 206)\n",
  18000. "\n"
  18001. ]
  18002. },
  18003. {
  18004. "data": {
  18005. "application/javascript": [
  18006. "/* Put everything inside the global mpl namespace */\n",
  18007. "window.mpl = {};\n",
  18008. "\n",
  18009. "\n",
  18010. "mpl.get_websocket_type = function() {\n",
  18011. " if (typeof(WebSocket) !== 'undefined') {\n",
  18012. " return WebSocket;\n",
  18013. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  18014. " return MozWebSocket;\n",
  18015. " } else {\n",
  18016. " alert('Your browser does not have WebSocket support.' +\n",
  18017. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  18018. " 'Firefox 4 and 5 are also supported but you ' +\n",
  18019. " 'have to enable WebSockets in about:config.');\n",
  18020. " };\n",
  18021. "}\n",
  18022. "\n",
  18023. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  18024. " this.id = figure_id;\n",
  18025. "\n",
  18026. " this.ws = websocket;\n",
  18027. "\n",
  18028. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  18029. "\n",
  18030. " if (!this.supports_binary) {\n",
  18031. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  18032. " if (warnings) {\n",
  18033. " warnings.style.display = 'block';\n",
  18034. " warnings.textContent = (\n",
  18035. " \"This browser does not support binary websocket messages. \" +\n",
  18036. " \"Performance may be slow.\");\n",
  18037. " }\n",
  18038. " }\n",
  18039. "\n",
  18040. " this.imageObj = new Image();\n",
  18041. "\n",
  18042. " this.context = undefined;\n",
  18043. " this.message = undefined;\n",
  18044. " this.canvas = undefined;\n",
  18045. " this.rubberband_canvas = undefined;\n",
  18046. " this.rubberband_context = undefined;\n",
  18047. " this.format_dropdown = undefined;\n",
  18048. "\n",
  18049. " this.image_mode = 'full';\n",
  18050. "\n",
  18051. " this.root = $('<div/>');\n",
  18052. " this._root_extra_style(this.root)\n",
  18053. " this.root.attr('style', 'display: inline-block');\n",
  18054. "\n",
  18055. " $(parent_element).append(this.root);\n",
  18056. "\n",
  18057. " this._init_header(this);\n",
  18058. " this._init_canvas(this);\n",
  18059. " this._init_toolbar(this);\n",
  18060. "\n",
  18061. " var fig = this;\n",
  18062. "\n",
  18063. " this.waiting = false;\n",
  18064. "\n",
  18065. " this.ws.onopen = function () {\n",
  18066. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  18067. " fig.send_message(\"send_image_mode\", {});\n",
  18068. " if (mpl.ratio != 1) {\n",
  18069. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  18070. " }\n",
  18071. " fig.send_message(\"refresh\", {});\n",
  18072. " }\n",
  18073. "\n",
  18074. " this.imageObj.onload = function() {\n",
  18075. " if (fig.image_mode == 'full') {\n",
  18076. " // Full images could contain transparency (where diff images\n",
  18077. " // almost always do), so we need to clear the canvas so that\n",
  18078. " // there is no ghosting.\n",
  18079. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  18080. " }\n",
  18081. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  18082. " };\n",
  18083. "\n",
  18084. " this.imageObj.onunload = function() {\n",
  18085. " fig.ws.close();\n",
  18086. " }\n",
  18087. "\n",
  18088. " this.ws.onmessage = this._make_on_message_function(this);\n",
  18089. "\n",
  18090. " this.ondownload = ondownload;\n",
  18091. "}\n",
  18092. "\n",
  18093. "mpl.figure.prototype._init_header = function() {\n",
  18094. " var titlebar = $(\n",
  18095. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  18096. " 'ui-helper-clearfix\"/>');\n",
  18097. " var titletext = $(\n",
  18098. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  18099. " 'text-align: center; padding: 3px;\"/>');\n",
  18100. " titlebar.append(titletext)\n",
  18101. " this.root.append(titlebar);\n",
  18102. " this.header = titletext[0];\n",
  18103. "}\n",
  18104. "\n",
  18105. "\n",
  18106. "\n",
  18107. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  18108. "\n",
  18109. "}\n",
  18110. "\n",
  18111. "\n",
  18112. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  18113. "\n",
  18114. "}\n",
  18115. "\n",
  18116. "mpl.figure.prototype._init_canvas = function() {\n",
  18117. " var fig = this;\n",
  18118. "\n",
  18119. " var canvas_div = $('<div/>');\n",
  18120. "\n",
  18121. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  18122. "\n",
  18123. " function canvas_keyboard_event(event) {\n",
  18124. " return fig.key_event(event, event['data']);\n",
  18125. " }\n",
  18126. "\n",
  18127. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  18128. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  18129. " this.canvas_div = canvas_div\n",
  18130. " this._canvas_extra_style(canvas_div)\n",
  18131. " this.root.append(canvas_div);\n",
  18132. "\n",
  18133. " var canvas = $('<canvas/>');\n",
  18134. " canvas.addClass('mpl-canvas');\n",
  18135. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  18136. "\n",
  18137. " this.canvas = canvas[0];\n",
  18138. " this.context = canvas[0].getContext(\"2d\");\n",
  18139. "\n",
  18140. " var backingStore = this.context.backingStorePixelRatio ||\n",
  18141. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  18142. "\tthis.context.mozBackingStorePixelRatio ||\n",
  18143. "\tthis.context.msBackingStorePixelRatio ||\n",
  18144. "\tthis.context.oBackingStorePixelRatio ||\n",
  18145. "\tthis.context.backingStorePixelRatio || 1;\n",
  18146. "\n",
  18147. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  18148. "\n",
  18149. " var rubberband = $('<canvas/>');\n",
  18150. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  18151. "\n",
  18152. " var pass_mouse_events = true;\n",
  18153. "\n",
  18154. " canvas_div.resizable({\n",
  18155. " start: function(event, ui) {\n",
  18156. " pass_mouse_events = false;\n",
  18157. " },\n",
  18158. " resize: function(event, ui) {\n",
  18159. " fig.request_resize(ui.size.width, ui.size.height);\n",
  18160. " },\n",
  18161. " stop: function(event, ui) {\n",
  18162. " pass_mouse_events = true;\n",
  18163. " fig.request_resize(ui.size.width, ui.size.height);\n",
  18164. " },\n",
  18165. " });\n",
  18166. "\n",
  18167. " function mouse_event_fn(event) {\n",
  18168. " if (pass_mouse_events)\n",
  18169. " return fig.mouse_event(event, event['data']);\n",
  18170. " }\n",
  18171. "\n",
  18172. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  18173. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  18174. " // Throttle sequential mouse events to 1 every 20ms.\n",
  18175. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  18176. "\n",
  18177. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  18178. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  18179. "\n",
  18180. " canvas_div.on(\"wheel\", function (event) {\n",
  18181. " event = event.originalEvent;\n",
  18182. " event['data'] = 'scroll'\n",
  18183. " if (event.deltaY < 0) {\n",
  18184. " event.step = 1;\n",
  18185. " } else {\n",
  18186. " event.step = -1;\n",
  18187. " }\n",
  18188. " mouse_event_fn(event);\n",
  18189. " });\n",
  18190. "\n",
  18191. " canvas_div.append(canvas);\n",
  18192. " canvas_div.append(rubberband);\n",
  18193. "\n",
  18194. " this.rubberband = rubberband;\n",
  18195. " this.rubberband_canvas = rubberband[0];\n",
  18196. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  18197. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  18198. "\n",
  18199. " this._resize_canvas = function(width, height) {\n",
  18200. " // Keep the size of the canvas, canvas container, and rubber band\n",
  18201. " // canvas in synch.\n",
  18202. " canvas_div.css('width', width)\n",
  18203. " canvas_div.css('height', height)\n",
  18204. "\n",
  18205. " canvas.attr('width', width * mpl.ratio);\n",
  18206. " canvas.attr('height', height * mpl.ratio);\n",
  18207. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  18208. "\n",
  18209. " rubberband.attr('width', width);\n",
  18210. " rubberband.attr('height', height);\n",
  18211. " }\n",
  18212. "\n",
  18213. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  18214. " // upon first draw.\n",
  18215. " this._resize_canvas(600, 600);\n",
  18216. "\n",
  18217. " // Disable right mouse context menu.\n",
  18218. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  18219. " return false;\n",
  18220. " });\n",
  18221. "\n",
  18222. " function set_focus () {\n",
  18223. " canvas.focus();\n",
  18224. " canvas_div.focus();\n",
  18225. " }\n",
  18226. "\n",
  18227. " window.setTimeout(set_focus, 100);\n",
  18228. "}\n",
  18229. "\n",
  18230. "mpl.figure.prototype._init_toolbar = function() {\n",
  18231. " var fig = this;\n",
  18232. "\n",
  18233. " var nav_element = $('<div/>')\n",
  18234. " nav_element.attr('style', 'width: 100%');\n",
  18235. " this.root.append(nav_element);\n",
  18236. "\n",
  18237. " // Define a callback function for later on.\n",
  18238. " function toolbar_event(event) {\n",
  18239. " return fig.toolbar_button_onclick(event['data']);\n",
  18240. " }\n",
  18241. " function toolbar_mouse_event(event) {\n",
  18242. " return fig.toolbar_button_onmouseover(event['data']);\n",
  18243. " }\n",
  18244. "\n",
  18245. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  18246. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  18247. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  18248. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  18249. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  18250. "\n",
  18251. " if (!name) {\n",
  18252. " // put a spacer in here.\n",
  18253. " continue;\n",
  18254. " }\n",
  18255. " var button = $('<button/>');\n",
  18256. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  18257. " 'ui-button-icon-only');\n",
  18258. " button.attr('role', 'button');\n",
  18259. " button.attr('aria-disabled', 'false');\n",
  18260. " button.click(method_name, toolbar_event);\n",
  18261. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  18262. "\n",
  18263. " var icon_img = $('<span/>');\n",
  18264. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  18265. " icon_img.addClass(image);\n",
  18266. " icon_img.addClass('ui-corner-all');\n",
  18267. "\n",
  18268. " var tooltip_span = $('<span/>');\n",
  18269. " tooltip_span.addClass('ui-button-text');\n",
  18270. " tooltip_span.html(tooltip);\n",
  18271. "\n",
  18272. " button.append(icon_img);\n",
  18273. " button.append(tooltip_span);\n",
  18274. "\n",
  18275. " nav_element.append(button);\n",
  18276. " }\n",
  18277. "\n",
  18278. " var fmt_picker_span = $('<span/>');\n",
  18279. "\n",
  18280. " var fmt_picker = $('<select/>');\n",
  18281. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  18282. " fmt_picker_span.append(fmt_picker);\n",
  18283. " nav_element.append(fmt_picker_span);\n",
  18284. " this.format_dropdown = fmt_picker[0];\n",
  18285. "\n",
  18286. " for (var ind in mpl.extensions) {\n",
  18287. " var fmt = mpl.extensions[ind];\n",
  18288. " var option = $(\n",
  18289. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  18290. " fmt_picker.append(option)\n",
  18291. " }\n",
  18292. "\n",
  18293. " // Add hover states to the ui-buttons\n",
  18294. " $( \".ui-button\" ).hover(\n",
  18295. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  18296. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  18297. " );\n",
  18298. "\n",
  18299. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  18300. " nav_element.append(status_bar);\n",
  18301. " this.message = status_bar[0];\n",
  18302. "}\n",
  18303. "\n",
  18304. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  18305. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  18306. " // which will in turn request a refresh of the image.\n",
  18307. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  18308. "}\n",
  18309. "\n",
  18310. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  18311. " properties['type'] = type;\n",
  18312. " properties['figure_id'] = this.id;\n",
  18313. " this.ws.send(JSON.stringify(properties));\n",
  18314. "}\n",
  18315. "\n",
  18316. "mpl.figure.prototype.send_draw_message = function() {\n",
  18317. " if (!this.waiting) {\n",
  18318. " this.waiting = true;\n",
  18319. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  18320. " }\n",
  18321. "}\n",
  18322. "\n",
  18323. "\n",
  18324. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  18325. " var format_dropdown = fig.format_dropdown;\n",
  18326. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  18327. " fig.ondownload(fig, format);\n",
  18328. "}\n",
  18329. "\n",
  18330. "\n",
  18331. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  18332. " var size = msg['size'];\n",
  18333. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  18334. " fig._resize_canvas(size[0], size[1]);\n",
  18335. " fig.send_message(\"refresh\", {});\n",
  18336. " };\n",
  18337. "}\n",
  18338. "\n",
  18339. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  18340. " var x0 = msg['x0'] / mpl.ratio;\n",
  18341. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  18342. " var x1 = msg['x1'] / mpl.ratio;\n",
  18343. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  18344. " x0 = Math.floor(x0) + 0.5;\n",
  18345. " y0 = Math.floor(y0) + 0.5;\n",
  18346. " x1 = Math.floor(x1) + 0.5;\n",
  18347. " y1 = Math.floor(y1) + 0.5;\n",
  18348. " var min_x = Math.min(x0, x1);\n",
  18349. " var min_y = Math.min(y0, y1);\n",
  18350. " var width = Math.abs(x1 - x0);\n",
  18351. " var height = Math.abs(y1 - y0);\n",
  18352. "\n",
  18353. " fig.rubberband_context.clearRect(\n",
  18354. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  18355. "\n",
  18356. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  18357. "}\n",
  18358. "\n",
  18359. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  18360. " // Updates the figure title.\n",
  18361. " fig.header.textContent = msg['label'];\n",
  18362. "}\n",
  18363. "\n",
  18364. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  18365. " var cursor = msg['cursor'];\n",
  18366. " switch(cursor)\n",
  18367. " {\n",
  18368. " case 0:\n",
  18369. " cursor = 'pointer';\n",
  18370. " break;\n",
  18371. " case 1:\n",
  18372. " cursor = 'default';\n",
  18373. " break;\n",
  18374. " case 2:\n",
  18375. " cursor = 'crosshair';\n",
  18376. " break;\n",
  18377. " case 3:\n",
  18378. " cursor = 'move';\n",
  18379. " break;\n",
  18380. " }\n",
  18381. " fig.rubberband_canvas.style.cursor = cursor;\n",
  18382. "}\n",
  18383. "\n",
  18384. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  18385. " fig.message.textContent = msg['message'];\n",
  18386. "}\n",
  18387. "\n",
  18388. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  18389. " // Request the server to send over a new figure.\n",
  18390. " fig.send_draw_message();\n",
  18391. "}\n",
  18392. "\n",
  18393. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  18394. " fig.image_mode = msg['mode'];\n",
  18395. "}\n",
  18396. "\n",
  18397. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  18398. " // Called whenever the canvas gets updated.\n",
  18399. " this.send_message(\"ack\", {});\n",
  18400. "}\n",
  18401. "\n",
  18402. "// A function to construct a web socket function for onmessage handling.\n",
  18403. "// Called in the figure constructor.\n",
  18404. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  18405. " return function socket_on_message(evt) {\n",
  18406. " if (evt.data instanceof Blob) {\n",
  18407. " /* FIXME: We get \"Resource interpreted as Image but\n",
  18408. " * transferred with MIME type text/plain:\" errors on\n",
  18409. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  18410. " * to be part of the websocket stream */\n",
  18411. " evt.data.type = \"image/png\";\n",
  18412. "\n",
  18413. " /* Free the memory for the previous frames */\n",
  18414. " if (fig.imageObj.src) {\n",
  18415. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  18416. " fig.imageObj.src);\n",
  18417. " }\n",
  18418. "\n",
  18419. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  18420. " evt.data);\n",
  18421. " fig.updated_canvas_event();\n",
  18422. " fig.waiting = false;\n",
  18423. " return;\n",
  18424. " }\n",
  18425. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  18426. " fig.imageObj.src = evt.data;\n",
  18427. " fig.updated_canvas_event();\n",
  18428. " fig.waiting = false;\n",
  18429. " return;\n",
  18430. " }\n",
  18431. "\n",
  18432. " var msg = JSON.parse(evt.data);\n",
  18433. " var msg_type = msg['type'];\n",
  18434. "\n",
  18435. " // Call the \"handle_{type}\" callback, which takes\n",
  18436. " // the figure and JSON message as its only arguments.\n",
  18437. " try {\n",
  18438. " var callback = fig[\"handle_\" + msg_type];\n",
  18439. " } catch (e) {\n",
  18440. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  18441. " return;\n",
  18442. " }\n",
  18443. "\n",
  18444. " if (callback) {\n",
  18445. " try {\n",
  18446. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  18447. " callback(fig, msg);\n",
  18448. " } catch (e) {\n",
  18449. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  18450. " }\n",
  18451. " }\n",
  18452. " };\n",
  18453. "}\n",
  18454. "\n",
  18455. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  18456. "mpl.findpos = function(e) {\n",
  18457. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  18458. " var targ;\n",
  18459. " if (!e)\n",
  18460. " e = window.event;\n",
  18461. " if (e.target)\n",
  18462. " targ = e.target;\n",
  18463. " else if (e.srcElement)\n",
  18464. " targ = e.srcElement;\n",
  18465. " if (targ.nodeType == 3) // defeat Safari bug\n",
  18466. " targ = targ.parentNode;\n",
  18467. "\n",
  18468. " // jQuery normalizes the pageX and pageY\n",
  18469. " // pageX,Y are the mouse positions relative to the document\n",
  18470. " // offset() returns the position of the element relative to the document\n",
  18471. " var x = e.pageX - $(targ).offset().left;\n",
  18472. " var y = e.pageY - $(targ).offset().top;\n",
  18473. "\n",
  18474. " return {\"x\": x, \"y\": y};\n",
  18475. "};\n",
  18476. "\n",
  18477. "/*\n",
  18478. " * return a copy of an object with only non-object keys\n",
  18479. " * we need this to avoid circular references\n",
  18480. " * http://stackoverflow.com/a/24161582/3208463\n",
  18481. " */\n",
  18482. "function simpleKeys (original) {\n",
  18483. " return Object.keys(original).reduce(function (obj, key) {\n",
  18484. " if (typeof original[key] !== 'object')\n",
  18485. " obj[key] = original[key]\n",
  18486. " return obj;\n",
  18487. " }, {});\n",
  18488. "}\n",
  18489. "\n",
  18490. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  18491. " var canvas_pos = mpl.findpos(event)\n",
  18492. "\n",
  18493. " if (name === 'button_press')\n",
  18494. " {\n",
  18495. " this.canvas.focus();\n",
  18496. " this.canvas_div.focus();\n",
  18497. " }\n",
  18498. "\n",
  18499. " var x = canvas_pos.x * mpl.ratio;\n",
  18500. " var y = canvas_pos.y * mpl.ratio;\n",
  18501. "\n",
  18502. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  18503. " step: event.step,\n",
  18504. " guiEvent: simpleKeys(event)});\n",
  18505. "\n",
  18506. " /* This prevents the web browser from automatically changing to\n",
  18507. " * the text insertion cursor when the button is pressed. We want\n",
  18508. " * to control all of the cursor setting manually through the\n",
  18509. " * 'cursor' event from matplotlib */\n",
  18510. " event.preventDefault();\n",
  18511. " return false;\n",
  18512. "}\n",
  18513. "\n",
  18514. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  18515. " // Handle any extra behaviour associated with a key event\n",
  18516. "}\n",
  18517. "\n",
  18518. "mpl.figure.prototype.key_event = function(event, name) {\n",
  18519. "\n",
  18520. " // Prevent repeat events\n",
  18521. " if (name == 'key_press')\n",
  18522. " {\n",
  18523. " if (event.which === this._key)\n",
  18524. " return;\n",
  18525. " else\n",
  18526. " this._key = event.which;\n",
  18527. " }\n",
  18528. " if (name == 'key_release')\n",
  18529. " this._key = null;\n",
  18530. "\n",
  18531. " var value = '';\n",
  18532. " if (event.ctrlKey && event.which != 17)\n",
  18533. " value += \"ctrl+\";\n",
  18534. " if (event.altKey && event.which != 18)\n",
  18535. " value += \"alt+\";\n",
  18536. " if (event.shiftKey && event.which != 16)\n",
  18537. " value += \"shift+\";\n",
  18538. "\n",
  18539. " value += 'k';\n",
  18540. " value += event.which.toString();\n",
  18541. "\n",
  18542. " this._key_event_extra(event, name);\n",
  18543. "\n",
  18544. " this.send_message(name, {key: value,\n",
  18545. " guiEvent: simpleKeys(event)});\n",
  18546. " return false;\n",
  18547. "}\n",
  18548. "\n",
  18549. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  18550. " if (name == 'download') {\n",
  18551. " this.handle_save(this, null);\n",
  18552. " } else {\n",
  18553. " this.send_message(\"toolbar_button\", {name: name});\n",
  18554. " }\n",
  18555. "};\n",
  18556. "\n",
  18557. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  18558. " this.message.textContent = tooltip;\n",
  18559. "};\n",
  18560. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  18561. "\n",
  18562. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  18563. "\n",
  18564. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  18565. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  18566. " // object with the appropriate methods. Currently this is a non binary\n",
  18567. " // socket, so there is still some room for performance tuning.\n",
  18568. " var ws = {};\n",
  18569. "\n",
  18570. " ws.close = function() {\n",
  18571. " comm.close()\n",
  18572. " };\n",
  18573. " ws.send = function(m) {\n",
  18574. " //console.log('sending', m);\n",
  18575. " comm.send(m);\n",
  18576. " };\n",
  18577. " // Register the callback with on_msg.\n",
  18578. " comm.on_msg(function(msg) {\n",
  18579. " //console.log('receiving', msg['content']['data'], msg);\n",
  18580. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  18581. " ws.onmessage(msg['content']['data'])\n",
  18582. " });\n",
  18583. " return ws;\n",
  18584. "}\n",
  18585. "\n",
  18586. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  18587. " // This is the function which gets called when the mpl process\n",
  18588. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  18589. "\n",
  18590. " var id = msg.content.data.id;\n",
  18591. " // Get hold of the div created by the display call when the Comm\n",
  18592. " // socket was opened in Python.\n",
  18593. " var element = $(\"#\" + id);\n",
  18594. " var ws_proxy = comm_websocket_adapter(comm)\n",
  18595. "\n",
  18596. " function ondownload(figure, format) {\n",
  18597. " window.open(figure.imageObj.src);\n",
  18598. " }\n",
  18599. "\n",
  18600. " var fig = new mpl.figure(id, ws_proxy,\n",
  18601. " ondownload,\n",
  18602. " element.get(0));\n",
  18603. "\n",
  18604. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  18605. " // web socket which is closed, not our websocket->open comm proxy.\n",
  18606. " ws_proxy.onopen();\n",
  18607. "\n",
  18608. " fig.parent_element = element.get(0);\n",
  18609. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  18610. " if (!fig.cell_info) {\n",
  18611. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  18612. " return;\n",
  18613. " }\n",
  18614. "\n",
  18615. " var output_index = fig.cell_info[2]\n",
  18616. " var cell = fig.cell_info[0];\n",
  18617. "\n",
  18618. "};\n",
  18619. "\n",
  18620. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  18621. " var width = fig.canvas.width/mpl.ratio\n",
  18622. " fig.root.unbind('remove')\n",
  18623. "\n",
  18624. " // Update the output cell to use the data from the current canvas.\n",
  18625. " fig.push_to_output();\n",
  18626. " var dataURL = fig.canvas.toDataURL();\n",
  18627. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  18628. " // the notebook keyboard shortcuts fail.\n",
  18629. " IPython.keyboard_manager.enable()\n",
  18630. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  18631. " fig.close_ws(fig, msg);\n",
  18632. "}\n",
  18633. "\n",
  18634. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  18635. " fig.send_message('closing', msg);\n",
  18636. " // fig.ws.close()\n",
  18637. "}\n",
  18638. "\n",
  18639. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  18640. " // Turn the data on the canvas into data in the output cell.\n",
  18641. " var width = this.canvas.width/mpl.ratio\n",
  18642. " var dataURL = this.canvas.toDataURL();\n",
  18643. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  18644. "}\n",
  18645. "\n",
  18646. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  18647. " // Tell IPython that the notebook contents must change.\n",
  18648. " IPython.notebook.set_dirty(true);\n",
  18649. " this.send_message(\"ack\", {});\n",
  18650. " var fig = this;\n",
  18651. " // Wait a second, then push the new image to the DOM so\n",
  18652. " // that it is saved nicely (might be nice to debounce this).\n",
  18653. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  18654. "}\n",
  18655. "\n",
  18656. "mpl.figure.prototype._init_toolbar = function() {\n",
  18657. " var fig = this;\n",
  18658. "\n",
  18659. " var nav_element = $('<div/>')\n",
  18660. " nav_element.attr('style', 'width: 100%');\n",
  18661. " this.root.append(nav_element);\n",
  18662. "\n",
  18663. " // Define a callback function for later on.\n",
  18664. " function toolbar_event(event) {\n",
  18665. " return fig.toolbar_button_onclick(event['data']);\n",
  18666. " }\n",
  18667. " function toolbar_mouse_event(event) {\n",
  18668. " return fig.toolbar_button_onmouseover(event['data']);\n",
  18669. " }\n",
  18670. "\n",
  18671. " for(var toolbar_ind in mpl.toolbar_items){\n",
  18672. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  18673. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  18674. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  18675. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  18676. "\n",
  18677. " if (!name) { continue; };\n",
  18678. "\n",
  18679. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  18680. " button.click(method_name, toolbar_event);\n",
  18681. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  18682. " nav_element.append(button);\n",
  18683. " }\n",
  18684. "\n",
  18685. " // Add the status bar.\n",
  18686. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  18687. " nav_element.append(status_bar);\n",
  18688. " this.message = status_bar[0];\n",
  18689. "\n",
  18690. " // Add the close button to the window.\n",
  18691. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  18692. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  18693. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  18694. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  18695. " buttongrp.append(button);\n",
  18696. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  18697. " titlebar.prepend(buttongrp);\n",
  18698. "}\n",
  18699. "\n",
  18700. "mpl.figure.prototype._root_extra_style = function(el){\n",
  18701. " var fig = this\n",
  18702. " el.on(\"remove\", function(){\n",
  18703. "\tfig.close_ws(fig, {});\n",
  18704. " });\n",
  18705. "}\n",
  18706. "\n",
  18707. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  18708. " // this is important to make the div 'focusable\n",
  18709. " el.attr('tabindex', 0)\n",
  18710. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  18711. " // off when our div gets focus\n",
  18712. "\n",
  18713. " // location in version 3\n",
  18714. " if (IPython.notebook.keyboard_manager) {\n",
  18715. " IPython.notebook.keyboard_manager.register_events(el);\n",
  18716. " }\n",
  18717. " else {\n",
  18718. " // location in version 2\n",
  18719. " IPython.keyboard_manager.register_events(el);\n",
  18720. " }\n",
  18721. "\n",
  18722. "}\n",
  18723. "\n",
  18724. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  18725. " var manager = IPython.notebook.keyboard_manager;\n",
  18726. " if (!manager)\n",
  18727. " manager = IPython.keyboard_manager;\n",
  18728. "\n",
  18729. " // Check for shift+enter\n",
  18730. " if (event.shiftKey && event.which == 13) {\n",
  18731. " this.canvas_div.blur();\n",
  18732. " event.shiftKey = false;\n",
  18733. " // Send a \"J\" for go to next cell\n",
  18734. " event.which = 74;\n",
  18735. " event.keyCode = 74;\n",
  18736. " manager.command_mode();\n",
  18737. " manager.handle_keydown(event);\n",
  18738. " }\n",
  18739. "}\n",
  18740. "\n",
  18741. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  18742. " fig.ondownload(fig, null);\n",
  18743. "}\n",
  18744. "\n",
  18745. "\n",
  18746. "mpl.find_output_cell = function(html_output) {\n",
  18747. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  18748. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  18749. " // IPython event is triggered only after the cells have been serialised, which for\n",
  18750. " // our purposes (turning an active figure into a static one), is too late.\n",
  18751. " var cells = IPython.notebook.get_cells();\n",
  18752. " var ncells = cells.length;\n",
  18753. " for (var i=0; i<ncells; i++) {\n",
  18754. " var cell = cells[i];\n",
  18755. " if (cell.cell_type === 'code'){\n",
  18756. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  18757. " var data = cell.output_area.outputs[j];\n",
  18758. " if (data.data) {\n",
  18759. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  18760. " data = data.data;\n",
  18761. " }\n",
  18762. " if (data['text/html'] == html_output) {\n",
  18763. " return [cell, data, j];\n",
  18764. " }\n",
  18765. " }\n",
  18766. " }\n",
  18767. " }\n",
  18768. "}\n",
  18769. "\n",
  18770. "// Register the function which deals with the matplotlib target/channel.\n",
  18771. "// The kernel may be null if the page has been refreshed.\n",
  18772. "if (IPython.notebook.kernel != null) {\n",
  18773. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  18774. "}\n"
  18775. ],
  18776. "text/plain": [
  18777. "<IPython.core.display.Javascript object>"
  18778. ]
  18779. },
  18780. "metadata": {},
  18781. "output_type": "display_data"
  18782. },
  18783. {
  18784. "data": {
  18785. "text/html": [
  18786. "<img src=\"data:image/png;base64,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DBgAAAA/AQMGQRAE+VowYAAAAPwEDBgEQRDka8GAAQAA8BMwYBAEQZCvBQMGAADAT8CAQRAEQb4WDBgAAAA/AQMGQRAE+VowYAAAAPwEDBgEQRDka8GAAQAA8BMwYBAEQZCvBQMGAADAT8CAQRAEQb4WDBgAAAA/AQMGQRAE+VowYAAAAPwEDBgEQRDka8GAAQAA8BMwYBAEQZCvBQMGAADAT8CAQRAEQb4WDBgAAAA/AQMGQRAE+VowYAAAAPwEDBgEQRDka8GAAQAA8BMwYBAEQZCvBQMGAADAT8CAQRAEQb4WDBgAAAA/AQMGQRAE+VowYAAAAPwEDBgEQRDka8GAAQAA8BMwYBAEQZCvBQMGAADAT8CAQRAEQb4WDBgAAAA/AQMGQRAE+VowYAAAAPwEDBgEQRDka8GAAQAA8BMwYBAEQZCvBQMGAADAT8CAQRAEQb4WDBgAAAA/AQMGQRAE+VowYAAAAPwEDBgEQRDka8GAAQAA8BMwYBAEQZCvBQMGAADAT8CAQRAEQb4WDBgAAAA/AQMGQRAE+VowYAAAAPwEDBgEQRDka8GAAQAA8BMwYBAEQZCvBQMGAADAT8CAQRAEQb4WDBgAAAA/AQMGQRAE+VowYAAAAPwEDBgEQRDka8GAAQAA8BMwYBAEQZCvBQMGAADAT8CAQRAEQb4WDBgAAAA/AQMGQRAE+VowYAAAAPwEDBgEQRDka8GAAQAA8BMwYBAEQZCvBQMGAADAT8CAQRAEQb4WDBgAAAA/AQMGQRAE+VowYAAAAPwEDBgEQRDka8GAAQAA8BMwYBAEQZCvBQMGAADAT8CAQRAEQb4WDBgAAAA/AQMGQRAE+VowYAAAAPwEDBgEQRDka8GAAQAA8BMwYBAEQZCvBQMGAADAT8CAQRAEQb4WDBgAAAA/AQMGQRAE+VowYAAAAPwEDBgEQRDka8GAAQAA8BMwYBAEQZCvBQMGAADAT8CAQRAEQb4WDBgAAAA/AQMGQRAE+VowYAAAAPwEDBgEQRDka8GAAQAA8BMwYBAEQZCvBQMGAADAT8CAQRAEQb4WDBgAAAA/AQMGQRAE+VowYAAAAPwEDBgEQRDka8GAAQAA8BMwYBAEQZCvBQMGAADAT8CAQRAEQb4WDBgAAAA/4OO1igAADBhJREFUAQMGQRAE+VowYAAAAPwEDBgEQRDka8GAAQAA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\" width=\"432\">"
  18787. ],
  18788. "text/plain": [
  18789. "<IPython.core.display.HTML object>"
  18790. ]
  18791. },
  18792. "metadata": {},
  18793. "output_type": "display_data"
  18794. },
  18795. {
  18796. "name": "stdout",
  18797. "output_type": "stream",
  18798. "text": [
  18799. "0.0 1.0\n",
  18800. "262.0\n",
  18801. "(358, 321)\n",
  18802. "\n"
  18803. ]
  18804. },
  18805. {
  18806. "data": {
  18807. "application/javascript": [
  18808. "/* Put everything inside the global mpl namespace */\n",
  18809. "window.mpl = {};\n",
  18810. "\n",
  18811. "\n",
  18812. "mpl.get_websocket_type = function() {\n",
  18813. " if (typeof(WebSocket) !== 'undefined') {\n",
  18814. " return WebSocket;\n",
  18815. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  18816. " return MozWebSocket;\n",
  18817. " } else {\n",
  18818. " alert('Your browser does not have WebSocket support.' +\n",
  18819. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  18820. " 'Firefox 4 and 5 are also supported but you ' +\n",
  18821. " 'have to enable WebSockets in about:config.');\n",
  18822. " };\n",
  18823. "}\n",
  18824. "\n",
  18825. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  18826. " this.id = figure_id;\n",
  18827. "\n",
  18828. " this.ws = websocket;\n",
  18829. "\n",
  18830. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  18831. "\n",
  18832. " if (!this.supports_binary) {\n",
  18833. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  18834. " if (warnings) {\n",
  18835. " warnings.style.display = 'block';\n",
  18836. " warnings.textContent = (\n",
  18837. " \"This browser does not support binary websocket messages. \" +\n",
  18838. " \"Performance may be slow.\");\n",
  18839. " }\n",
  18840. " }\n",
  18841. "\n",
  18842. " this.imageObj = new Image();\n",
  18843. "\n",
  18844. " this.context = undefined;\n",
  18845. " this.message = undefined;\n",
  18846. " this.canvas = undefined;\n",
  18847. " this.rubberband_canvas = undefined;\n",
  18848. " this.rubberband_context = undefined;\n",
  18849. " this.format_dropdown = undefined;\n",
  18850. "\n",
  18851. " this.image_mode = 'full';\n",
  18852. "\n",
  18853. " this.root = $('<div/>');\n",
  18854. " this._root_extra_style(this.root)\n",
  18855. " this.root.attr('style', 'display: inline-block');\n",
  18856. "\n",
  18857. " $(parent_element).append(this.root);\n",
  18858. "\n",
  18859. " this._init_header(this);\n",
  18860. " this._init_canvas(this);\n",
  18861. " this._init_toolbar(this);\n",
  18862. "\n",
  18863. " var fig = this;\n",
  18864. "\n",
  18865. " this.waiting = false;\n",
  18866. "\n",
  18867. " this.ws.onopen = function () {\n",
  18868. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  18869. " fig.send_message(\"send_image_mode\", {});\n",
  18870. " if (mpl.ratio != 1) {\n",
  18871. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  18872. " }\n",
  18873. " fig.send_message(\"refresh\", {});\n",
  18874. " }\n",
  18875. "\n",
  18876. " this.imageObj.onload = function() {\n",
  18877. " if (fig.image_mode == 'full') {\n",
  18878. " // Full images could contain transparency (where diff images\n",
  18879. " // almost always do), so we need to clear the canvas so that\n",
  18880. " // there is no ghosting.\n",
  18881. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  18882. " }\n",
  18883. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  18884. " };\n",
  18885. "\n",
  18886. " this.imageObj.onunload = function() {\n",
  18887. " fig.ws.close();\n",
  18888. " }\n",
  18889. "\n",
  18890. " this.ws.onmessage = this._make_on_message_function(this);\n",
  18891. "\n",
  18892. " this.ondownload = ondownload;\n",
  18893. "}\n",
  18894. "\n",
  18895. "mpl.figure.prototype._init_header = function() {\n",
  18896. " var titlebar = $(\n",
  18897. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  18898. " 'ui-helper-clearfix\"/>');\n",
  18899. " var titletext = $(\n",
  18900. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  18901. " 'text-align: center; padding: 3px;\"/>');\n",
  18902. " titlebar.append(titletext)\n",
  18903. " this.root.append(titlebar);\n",
  18904. " this.header = titletext[0];\n",
  18905. "}\n",
  18906. "\n",
  18907. "\n",
  18908. "\n",
  18909. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  18910. "\n",
  18911. "}\n",
  18912. "\n",
  18913. "\n",
  18914. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  18915. "\n",
  18916. "}\n",
  18917. "\n",
  18918. "mpl.figure.prototype._init_canvas = function() {\n",
  18919. " var fig = this;\n",
  18920. "\n",
  18921. " var canvas_div = $('<div/>');\n",
  18922. "\n",
  18923. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  18924. "\n",
  18925. " function canvas_keyboard_event(event) {\n",
  18926. " return fig.key_event(event, event['data']);\n",
  18927. " }\n",
  18928. "\n",
  18929. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  18930. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  18931. " this.canvas_div = canvas_div\n",
  18932. " this._canvas_extra_style(canvas_div)\n",
  18933. " this.root.append(canvas_div);\n",
  18934. "\n",
  18935. " var canvas = $('<canvas/>');\n",
  18936. " canvas.addClass('mpl-canvas');\n",
  18937. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  18938. "\n",
  18939. " this.canvas = canvas[0];\n",
  18940. " this.context = canvas[0].getContext(\"2d\");\n",
  18941. "\n",
  18942. " var backingStore = this.context.backingStorePixelRatio ||\n",
  18943. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  18944. "\tthis.context.mozBackingStorePixelRatio ||\n",
  18945. "\tthis.context.msBackingStorePixelRatio ||\n",
  18946. "\tthis.context.oBackingStorePixelRatio ||\n",
  18947. "\tthis.context.backingStorePixelRatio || 1;\n",
  18948. "\n",
  18949. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  18950. "\n",
  18951. " var rubberband = $('<canvas/>');\n",
  18952. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  18953. "\n",
  18954. " var pass_mouse_events = true;\n",
  18955. "\n",
  18956. " canvas_div.resizable({\n",
  18957. " start: function(event, ui) {\n",
  18958. " pass_mouse_events = false;\n",
  18959. " },\n",
  18960. " resize: function(event, ui) {\n",
  18961. " fig.request_resize(ui.size.width, ui.size.height);\n",
  18962. " },\n",
  18963. " stop: function(event, ui) {\n",
  18964. " pass_mouse_events = true;\n",
  18965. " fig.request_resize(ui.size.width, ui.size.height);\n",
  18966. " },\n",
  18967. " });\n",
  18968. "\n",
  18969. " function mouse_event_fn(event) {\n",
  18970. " if (pass_mouse_events)\n",
  18971. " return fig.mouse_event(event, event['data']);\n",
  18972. " }\n",
  18973. "\n",
  18974. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  18975. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  18976. " // Throttle sequential mouse events to 1 every 20ms.\n",
  18977. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  18978. "\n",
  18979. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  18980. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  18981. "\n",
  18982. " canvas_div.on(\"wheel\", function (event) {\n",
  18983. " event = event.originalEvent;\n",
  18984. " event['data'] = 'scroll'\n",
  18985. " if (event.deltaY < 0) {\n",
  18986. " event.step = 1;\n",
  18987. " } else {\n",
  18988. " event.step = -1;\n",
  18989. " }\n",
  18990. " mouse_event_fn(event);\n",
  18991. " });\n",
  18992. "\n",
  18993. " canvas_div.append(canvas);\n",
  18994. " canvas_div.append(rubberband);\n",
  18995. "\n",
  18996. " this.rubberband = rubberband;\n",
  18997. " this.rubberband_canvas = rubberband[0];\n",
  18998. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  18999. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  19000. "\n",
  19001. " this._resize_canvas = function(width, height) {\n",
  19002. " // Keep the size of the canvas, canvas container, and rubber band\n",
  19003. " // canvas in synch.\n",
  19004. " canvas_div.css('width', width)\n",
  19005. " canvas_div.css('height', height)\n",
  19006. "\n",
  19007. " canvas.attr('width', width * mpl.ratio);\n",
  19008. " canvas.attr('height', height * mpl.ratio);\n",
  19009. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  19010. "\n",
  19011. " rubberband.attr('width', width);\n",
  19012. " rubberband.attr('height', height);\n",
  19013. " }\n",
  19014. "\n",
  19015. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  19016. " // upon first draw.\n",
  19017. " this._resize_canvas(600, 600);\n",
  19018. "\n",
  19019. " // Disable right mouse context menu.\n",
  19020. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  19021. " return false;\n",
  19022. " });\n",
  19023. "\n",
  19024. " function set_focus () {\n",
  19025. " canvas.focus();\n",
  19026. " canvas_div.focus();\n",
  19027. " }\n",
  19028. "\n",
  19029. " window.setTimeout(set_focus, 100);\n",
  19030. "}\n",
  19031. "\n",
  19032. "mpl.figure.prototype._init_toolbar = function() {\n",
  19033. " var fig = this;\n",
  19034. "\n",
  19035. " var nav_element = $('<div/>')\n",
  19036. " nav_element.attr('style', 'width: 100%');\n",
  19037. " this.root.append(nav_element);\n",
  19038. "\n",
  19039. " // Define a callback function for later on.\n",
  19040. " function toolbar_event(event) {\n",
  19041. " return fig.toolbar_button_onclick(event['data']);\n",
  19042. " }\n",
  19043. " function toolbar_mouse_event(event) {\n",
  19044. " return fig.toolbar_button_onmouseover(event['data']);\n",
  19045. " }\n",
  19046. "\n",
  19047. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  19048. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  19049. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  19050. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  19051. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  19052. "\n",
  19053. " if (!name) {\n",
  19054. " // put a spacer in here.\n",
  19055. " continue;\n",
  19056. " }\n",
  19057. " var button = $('<button/>');\n",
  19058. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  19059. " 'ui-button-icon-only');\n",
  19060. " button.attr('role', 'button');\n",
  19061. " button.attr('aria-disabled', 'false');\n",
  19062. " button.click(method_name, toolbar_event);\n",
  19063. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  19064. "\n",
  19065. " var icon_img = $('<span/>');\n",
  19066. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  19067. " icon_img.addClass(image);\n",
  19068. " icon_img.addClass('ui-corner-all');\n",
  19069. "\n",
  19070. " var tooltip_span = $('<span/>');\n",
  19071. " tooltip_span.addClass('ui-button-text');\n",
  19072. " tooltip_span.html(tooltip);\n",
  19073. "\n",
  19074. " button.append(icon_img);\n",
  19075. " button.append(tooltip_span);\n",
  19076. "\n",
  19077. " nav_element.append(button);\n",
  19078. " }\n",
  19079. "\n",
  19080. " var fmt_picker_span = $('<span/>');\n",
  19081. "\n",
  19082. " var fmt_picker = $('<select/>');\n",
  19083. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  19084. " fmt_picker_span.append(fmt_picker);\n",
  19085. " nav_element.append(fmt_picker_span);\n",
  19086. " this.format_dropdown = fmt_picker[0];\n",
  19087. "\n",
  19088. " for (var ind in mpl.extensions) {\n",
  19089. " var fmt = mpl.extensions[ind];\n",
  19090. " var option = $(\n",
  19091. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  19092. " fmt_picker.append(option)\n",
  19093. " }\n",
  19094. "\n",
  19095. " // Add hover states to the ui-buttons\n",
  19096. " $( \".ui-button\" ).hover(\n",
  19097. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  19098. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  19099. " );\n",
  19100. "\n",
  19101. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  19102. " nav_element.append(status_bar);\n",
  19103. " this.message = status_bar[0];\n",
  19104. "}\n",
  19105. "\n",
  19106. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  19107. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  19108. " // which will in turn request a refresh of the image.\n",
  19109. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  19110. "}\n",
  19111. "\n",
  19112. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  19113. " properties['type'] = type;\n",
  19114. " properties['figure_id'] = this.id;\n",
  19115. " this.ws.send(JSON.stringify(properties));\n",
  19116. "}\n",
  19117. "\n",
  19118. "mpl.figure.prototype.send_draw_message = function() {\n",
  19119. " if (!this.waiting) {\n",
  19120. " this.waiting = true;\n",
  19121. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  19122. " }\n",
  19123. "}\n",
  19124. "\n",
  19125. "\n",
  19126. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  19127. " var format_dropdown = fig.format_dropdown;\n",
  19128. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  19129. " fig.ondownload(fig, format);\n",
  19130. "}\n",
  19131. "\n",
  19132. "\n",
  19133. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  19134. " var size = msg['size'];\n",
  19135. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  19136. " fig._resize_canvas(size[0], size[1]);\n",
  19137. " fig.send_message(\"refresh\", {});\n",
  19138. " };\n",
  19139. "}\n",
  19140. "\n",
  19141. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  19142. " var x0 = msg['x0'] / mpl.ratio;\n",
  19143. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  19144. " var x1 = msg['x1'] / mpl.ratio;\n",
  19145. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  19146. " x0 = Math.floor(x0) + 0.5;\n",
  19147. " y0 = Math.floor(y0) + 0.5;\n",
  19148. " x1 = Math.floor(x1) + 0.5;\n",
  19149. " y1 = Math.floor(y1) + 0.5;\n",
  19150. " var min_x = Math.min(x0, x1);\n",
  19151. " var min_y = Math.min(y0, y1);\n",
  19152. " var width = Math.abs(x1 - x0);\n",
  19153. " var height = Math.abs(y1 - y0);\n",
  19154. "\n",
  19155. " fig.rubberband_context.clearRect(\n",
  19156. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  19157. "\n",
  19158. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  19159. "}\n",
  19160. "\n",
  19161. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  19162. " // Updates the figure title.\n",
  19163. " fig.header.textContent = msg['label'];\n",
  19164. "}\n",
  19165. "\n",
  19166. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  19167. " var cursor = msg['cursor'];\n",
  19168. " switch(cursor)\n",
  19169. " {\n",
  19170. " case 0:\n",
  19171. " cursor = 'pointer';\n",
  19172. " break;\n",
  19173. " case 1:\n",
  19174. " cursor = 'default';\n",
  19175. " break;\n",
  19176. " case 2:\n",
  19177. " cursor = 'crosshair';\n",
  19178. " break;\n",
  19179. " case 3:\n",
  19180. " cursor = 'move';\n",
  19181. " break;\n",
  19182. " }\n",
  19183. " fig.rubberband_canvas.style.cursor = cursor;\n",
  19184. "}\n",
  19185. "\n",
  19186. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  19187. " fig.message.textContent = msg['message'];\n",
  19188. "}\n",
  19189. "\n",
  19190. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  19191. " // Request the server to send over a new figure.\n",
  19192. " fig.send_draw_message();\n",
  19193. "}\n",
  19194. "\n",
  19195. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  19196. " fig.image_mode = msg['mode'];\n",
  19197. "}\n",
  19198. "\n",
  19199. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  19200. " // Called whenever the canvas gets updated.\n",
  19201. " this.send_message(\"ack\", {});\n",
  19202. "}\n",
  19203. "\n",
  19204. "// A function to construct a web socket function for onmessage handling.\n",
  19205. "// Called in the figure constructor.\n",
  19206. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  19207. " return function socket_on_message(evt) {\n",
  19208. " if (evt.data instanceof Blob) {\n",
  19209. " /* FIXME: We get \"Resource interpreted as Image but\n",
  19210. " * transferred with MIME type text/plain:\" errors on\n",
  19211. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  19212. " * to be part of the websocket stream */\n",
  19213. " evt.data.type = \"image/png\";\n",
  19214. "\n",
  19215. " /* Free the memory for the previous frames */\n",
  19216. " if (fig.imageObj.src) {\n",
  19217. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  19218. " fig.imageObj.src);\n",
  19219. " }\n",
  19220. "\n",
  19221. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  19222. " evt.data);\n",
  19223. " fig.updated_canvas_event();\n",
  19224. " fig.waiting = false;\n",
  19225. " return;\n",
  19226. " }\n",
  19227. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  19228. " fig.imageObj.src = evt.data;\n",
  19229. " fig.updated_canvas_event();\n",
  19230. " fig.waiting = false;\n",
  19231. " return;\n",
  19232. " }\n",
  19233. "\n",
  19234. " var msg = JSON.parse(evt.data);\n",
  19235. " var msg_type = msg['type'];\n",
  19236. "\n",
  19237. " // Call the \"handle_{type}\" callback, which takes\n",
  19238. " // the figure and JSON message as its only arguments.\n",
  19239. " try {\n",
  19240. " var callback = fig[\"handle_\" + msg_type];\n",
  19241. " } catch (e) {\n",
  19242. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  19243. " return;\n",
  19244. " }\n",
  19245. "\n",
  19246. " if (callback) {\n",
  19247. " try {\n",
  19248. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  19249. " callback(fig, msg);\n",
  19250. " } catch (e) {\n",
  19251. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  19252. " }\n",
  19253. " }\n",
  19254. " };\n",
  19255. "}\n",
  19256. "\n",
  19257. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  19258. "mpl.findpos = function(e) {\n",
  19259. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  19260. " var targ;\n",
  19261. " if (!e)\n",
  19262. " e = window.event;\n",
  19263. " if (e.target)\n",
  19264. " targ = e.target;\n",
  19265. " else if (e.srcElement)\n",
  19266. " targ = e.srcElement;\n",
  19267. " if (targ.nodeType == 3) // defeat Safari bug\n",
  19268. " targ = targ.parentNode;\n",
  19269. "\n",
  19270. " // jQuery normalizes the pageX and pageY\n",
  19271. " // pageX,Y are the mouse positions relative to the document\n",
  19272. " // offset() returns the position of the element relative to the document\n",
  19273. " var x = e.pageX - $(targ).offset().left;\n",
  19274. " var y = e.pageY - $(targ).offset().top;\n",
  19275. "\n",
  19276. " return {\"x\": x, \"y\": y};\n",
  19277. "};\n",
  19278. "\n",
  19279. "/*\n",
  19280. " * return a copy of an object with only non-object keys\n",
  19281. " * we need this to avoid circular references\n",
  19282. " * http://stackoverflow.com/a/24161582/3208463\n",
  19283. " */\n",
  19284. "function simpleKeys (original) {\n",
  19285. " return Object.keys(original).reduce(function (obj, key) {\n",
  19286. " if (typeof original[key] !== 'object')\n",
  19287. " obj[key] = original[key]\n",
  19288. " return obj;\n",
  19289. " }, {});\n",
  19290. "}\n",
  19291. "\n",
  19292. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  19293. " var canvas_pos = mpl.findpos(event)\n",
  19294. "\n",
  19295. " if (name === 'button_press')\n",
  19296. " {\n",
  19297. " this.canvas.focus();\n",
  19298. " this.canvas_div.focus();\n",
  19299. " }\n",
  19300. "\n",
  19301. " var x = canvas_pos.x * mpl.ratio;\n",
  19302. " var y = canvas_pos.y * mpl.ratio;\n",
  19303. "\n",
  19304. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  19305. " step: event.step,\n",
  19306. " guiEvent: simpleKeys(event)});\n",
  19307. "\n",
  19308. " /* This prevents the web browser from automatically changing to\n",
  19309. " * the text insertion cursor when the button is pressed. We want\n",
  19310. " * to control all of the cursor setting manually through the\n",
  19311. " * 'cursor' event from matplotlib */\n",
  19312. " event.preventDefault();\n",
  19313. " return false;\n",
  19314. "}\n",
  19315. "\n",
  19316. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  19317. " // Handle any extra behaviour associated with a key event\n",
  19318. "}\n",
  19319. "\n",
  19320. "mpl.figure.prototype.key_event = function(event, name) {\n",
  19321. "\n",
  19322. " // Prevent repeat events\n",
  19323. " if (name == 'key_press')\n",
  19324. " {\n",
  19325. " if (event.which === this._key)\n",
  19326. " return;\n",
  19327. " else\n",
  19328. " this._key = event.which;\n",
  19329. " }\n",
  19330. " if (name == 'key_release')\n",
  19331. " this._key = null;\n",
  19332. "\n",
  19333. " var value = '';\n",
  19334. " if (event.ctrlKey && event.which != 17)\n",
  19335. " value += \"ctrl+\";\n",
  19336. " if (event.altKey && event.which != 18)\n",
  19337. " value += \"alt+\";\n",
  19338. " if (event.shiftKey && event.which != 16)\n",
  19339. " value += \"shift+\";\n",
  19340. "\n",
  19341. " value += 'k';\n",
  19342. " value += event.which.toString();\n",
  19343. "\n",
  19344. " this._key_event_extra(event, name);\n",
  19345. "\n",
  19346. " this.send_message(name, {key: value,\n",
  19347. " guiEvent: simpleKeys(event)});\n",
  19348. " return false;\n",
  19349. "}\n",
  19350. "\n",
  19351. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  19352. " if (name == 'download') {\n",
  19353. " this.handle_save(this, null);\n",
  19354. " } else {\n",
  19355. " this.send_message(\"toolbar_button\", {name: name});\n",
  19356. " }\n",
  19357. "};\n",
  19358. "\n",
  19359. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  19360. " this.message.textContent = tooltip;\n",
  19361. "};\n",
  19362. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  19363. "\n",
  19364. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  19365. "\n",
  19366. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  19367. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  19368. " // object with the appropriate methods. Currently this is a non binary\n",
  19369. " // socket, so there is still some room for performance tuning.\n",
  19370. " var ws = {};\n",
  19371. "\n",
  19372. " ws.close = function() {\n",
  19373. " comm.close()\n",
  19374. " };\n",
  19375. " ws.send = function(m) {\n",
  19376. " //console.log('sending', m);\n",
  19377. " comm.send(m);\n",
  19378. " };\n",
  19379. " // Register the callback with on_msg.\n",
  19380. " comm.on_msg(function(msg) {\n",
  19381. " //console.log('receiving', msg['content']['data'], msg);\n",
  19382. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  19383. " ws.onmessage(msg['content']['data'])\n",
  19384. " });\n",
  19385. " return ws;\n",
  19386. "}\n",
  19387. "\n",
  19388. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  19389. " // This is the function which gets called when the mpl process\n",
  19390. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  19391. "\n",
  19392. " var id = msg.content.data.id;\n",
  19393. " // Get hold of the div created by the display call when the Comm\n",
  19394. " // socket was opened in Python.\n",
  19395. " var element = $(\"#\" + id);\n",
  19396. " var ws_proxy = comm_websocket_adapter(comm)\n",
  19397. "\n",
  19398. " function ondownload(figure, format) {\n",
  19399. " window.open(figure.imageObj.src);\n",
  19400. " }\n",
  19401. "\n",
  19402. " var fig = new mpl.figure(id, ws_proxy,\n",
  19403. " ondownload,\n",
  19404. " element.get(0));\n",
  19405. "\n",
  19406. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  19407. " // web socket which is closed, not our websocket->open comm proxy.\n",
  19408. " ws_proxy.onopen();\n",
  19409. "\n",
  19410. " fig.parent_element = element.get(0);\n",
  19411. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  19412. " if (!fig.cell_info) {\n",
  19413. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  19414. " return;\n",
  19415. " }\n",
  19416. "\n",
  19417. " var output_index = fig.cell_info[2]\n",
  19418. " var cell = fig.cell_info[0];\n",
  19419. "\n",
  19420. "};\n",
  19421. "\n",
  19422. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  19423. " var width = fig.canvas.width/mpl.ratio\n",
  19424. " fig.root.unbind('remove')\n",
  19425. "\n",
  19426. " // Update the output cell to use the data from the current canvas.\n",
  19427. " fig.push_to_output();\n",
  19428. " var dataURL = fig.canvas.toDataURL();\n",
  19429. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  19430. " // the notebook keyboard shortcuts fail.\n",
  19431. " IPython.keyboard_manager.enable()\n",
  19432. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  19433. " fig.close_ws(fig, msg);\n",
  19434. "}\n",
  19435. "\n",
  19436. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  19437. " fig.send_message('closing', msg);\n",
  19438. " // fig.ws.close()\n",
  19439. "}\n",
  19440. "\n",
  19441. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  19442. " // Turn the data on the canvas into data in the output cell.\n",
  19443. " var width = this.canvas.width/mpl.ratio\n",
  19444. " var dataURL = this.canvas.toDataURL();\n",
  19445. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  19446. "}\n",
  19447. "\n",
  19448. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  19449. " // Tell IPython that the notebook contents must change.\n",
  19450. " IPython.notebook.set_dirty(true);\n",
  19451. " this.send_message(\"ack\", {});\n",
  19452. " var fig = this;\n",
  19453. " // Wait a second, then push the new image to the DOM so\n",
  19454. " // that it is saved nicely (might be nice to debounce this).\n",
  19455. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  19456. "}\n",
  19457. "\n",
  19458. "mpl.figure.prototype._init_toolbar = function() {\n",
  19459. " var fig = this;\n",
  19460. "\n",
  19461. " var nav_element = $('<div/>')\n",
  19462. " nav_element.attr('style', 'width: 100%');\n",
  19463. " this.root.append(nav_element);\n",
  19464. "\n",
  19465. " // Define a callback function for later on.\n",
  19466. " function toolbar_event(event) {\n",
  19467. " return fig.toolbar_button_onclick(event['data']);\n",
  19468. " }\n",
  19469. " function toolbar_mouse_event(event) {\n",
  19470. " return fig.toolbar_button_onmouseover(event['data']);\n",
  19471. " }\n",
  19472. "\n",
  19473. " for(var toolbar_ind in mpl.toolbar_items){\n",
  19474. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  19475. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  19476. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  19477. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  19478. "\n",
  19479. " if (!name) { continue; };\n",
  19480. "\n",
  19481. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  19482. " button.click(method_name, toolbar_event);\n",
  19483. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  19484. " nav_element.append(button);\n",
  19485. " }\n",
  19486. "\n",
  19487. " // Add the status bar.\n",
  19488. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  19489. " nav_element.append(status_bar);\n",
  19490. " this.message = status_bar[0];\n",
  19491. "\n",
  19492. " // Add the close button to the window.\n",
  19493. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  19494. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  19495. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  19496. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  19497. " buttongrp.append(button);\n",
  19498. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  19499. " titlebar.prepend(buttongrp);\n",
  19500. "}\n",
  19501. "\n",
  19502. "mpl.figure.prototype._root_extra_style = function(el){\n",
  19503. " var fig = this\n",
  19504. " el.on(\"remove\", function(){\n",
  19505. "\tfig.close_ws(fig, {});\n",
  19506. " });\n",
  19507. "}\n",
  19508. "\n",
  19509. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  19510. " // this is important to make the div 'focusable\n",
  19511. " el.attr('tabindex', 0)\n",
  19512. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  19513. " // off when our div gets focus\n",
  19514. "\n",
  19515. " // location in version 3\n",
  19516. " if (IPython.notebook.keyboard_manager) {\n",
  19517. " IPython.notebook.keyboard_manager.register_events(el);\n",
  19518. " }\n",
  19519. " else {\n",
  19520. " // location in version 2\n",
  19521. " IPython.keyboard_manager.register_events(el);\n",
  19522. " }\n",
  19523. "\n",
  19524. "}\n",
  19525. "\n",
  19526. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  19527. " var manager = IPython.notebook.keyboard_manager;\n",
  19528. " if (!manager)\n",
  19529. " manager = IPython.keyboard_manager;\n",
  19530. "\n",
  19531. " // Check for shift+enter\n",
  19532. " if (event.shiftKey && event.which == 13) {\n",
  19533. " this.canvas_div.blur();\n",
  19534. " event.shiftKey = false;\n",
  19535. " // Send a \"J\" for go to next cell\n",
  19536. " event.which = 74;\n",
  19537. " event.keyCode = 74;\n",
  19538. " manager.command_mode();\n",
  19539. " manager.handle_keydown(event);\n",
  19540. " }\n",
  19541. "}\n",
  19542. "\n",
  19543. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  19544. " fig.ondownload(fig, null);\n",
  19545. "}\n",
  19546. "\n",
  19547. "\n",
  19548. "mpl.find_output_cell = function(html_output) {\n",
  19549. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  19550. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  19551. " // IPython event is triggered only after the cells have been serialised, which for\n",
  19552. " // our purposes (turning an active figure into a static one), is too late.\n",
  19553. " var cells = IPython.notebook.get_cells();\n",
  19554. " var ncells = cells.length;\n",
  19555. " for (var i=0; i<ncells; i++) {\n",
  19556. " var cell = cells[i];\n",
  19557. " if (cell.cell_type === 'code'){\n",
  19558. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  19559. " var data = cell.output_area.outputs[j];\n",
  19560. " if (data.data) {\n",
  19561. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  19562. " data = data.data;\n",
  19563. " }\n",
  19564. " if (data['text/html'] == html_output) {\n",
  19565. " return [cell, data, j];\n",
  19566. " }\n",
  19567. " }\n",
  19568. " }\n",
  19569. " }\n",
  19570. "}\n",
  19571. "\n",
  19572. "// Register the function which deals with the matplotlib target/channel.\n",
  19573. "// The kernel may be null if the page has been refreshed.\n",
  19574. "if (IPython.notebook.kernel != null) {\n",
  19575. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  19576. "}\n"
  19577. ],
  19578. "text/plain": [
  19579. "<IPython.core.display.Javascript object>"
  19580. ]
  19581. },
  19582. "metadata": {},
  19583. "output_type": "display_data"
  19584. },
  19585. {
  19586. "data": {
  19587. "text/html": [
  19588. "<img src=\"data:image/png;base64,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+9yJPOiRASZJqs4AA1gsW5N8IcnXkrxgPLaU6QPssfH4eTM+1sHx/Fnjr184/vqJGbd/6Xj+O8fxOO+b0SEDTJLUnAEGsFiuT/KjPPu7WkuZPsCeGY9vnfGxHs6zv9v18+OvvzXj9j81nn/6OB6nASZJ2pQZYACL49eSHE7y/hXHl7LxBtgsnoIoSarOAANYDFszPO3wK0nOWHFuKRvvKYizGGCSpOoMMIDFcE6O/sDlY/XB8T7ehEOSpDlngAEshhckuWlG/5ajw+imJL893sfb0EuSNOcMMACWMv0piBfGD2KWJGmuGWAALGX6AEuSa8Zz+5PsyfCzw/aNx3bN+HgfyNGnJ+4e77d/PHb1Oh+rASZJqs4AA2ApswdYklyZ5M4Mb65xKMm9SXYe42O+dbzdofF+dya5Yv0P1QCTJHVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQ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\" width=\"432\">"
  19589. ],
  19590. "text/plain": [
  19591. "<IPython.core.display.HTML object>"
  19592. ]
  19593. },
  19594. "metadata": {},
  19595. "output_type": "display_data"
  19596. },
  19597. {
  19598. "name": "stdout",
  19599. "output_type": "stream",
  19600. "text": [
  19601. "0 1\n",
  19602. "274\n",
  19603. "(358, 317)\n",
  19604. "\n"
  19605. ]
  19606. },
  19607. {
  19608. "data": {
  19609. "application/javascript": [
  19610. "/* Put everything inside the global mpl namespace */\n",
  19611. "window.mpl = {};\n",
  19612. "\n",
  19613. "\n",
  19614. "mpl.get_websocket_type = function() {\n",
  19615. " if (typeof(WebSocket) !== 'undefined') {\n",
  19616. " return WebSocket;\n",
  19617. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  19618. " return MozWebSocket;\n",
  19619. " } else {\n",
  19620. " alert('Your browser does not have WebSocket support.' +\n",
  19621. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  19622. " 'Firefox 4 and 5 are also supported but you ' +\n",
  19623. " 'have to enable WebSockets in about:config.');\n",
  19624. " };\n",
  19625. "}\n",
  19626. "\n",
  19627. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  19628. " this.id = figure_id;\n",
  19629. "\n",
  19630. " this.ws = websocket;\n",
  19631. "\n",
  19632. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  19633. "\n",
  19634. " if (!this.supports_binary) {\n",
  19635. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  19636. " if (warnings) {\n",
  19637. " warnings.style.display = 'block';\n",
  19638. " warnings.textContent = (\n",
  19639. " \"This browser does not support binary websocket messages. \" +\n",
  19640. " \"Performance may be slow.\");\n",
  19641. " }\n",
  19642. " }\n",
  19643. "\n",
  19644. " this.imageObj = new Image();\n",
  19645. "\n",
  19646. " this.context = undefined;\n",
  19647. " this.message = undefined;\n",
  19648. " this.canvas = undefined;\n",
  19649. " this.rubberband_canvas = undefined;\n",
  19650. " this.rubberband_context = undefined;\n",
  19651. " this.format_dropdown = undefined;\n",
  19652. "\n",
  19653. " this.image_mode = 'full';\n",
  19654. "\n",
  19655. " this.root = $('<div/>');\n",
  19656. " this._root_extra_style(this.root)\n",
  19657. " this.root.attr('style', 'display: inline-block');\n",
  19658. "\n",
  19659. " $(parent_element).append(this.root);\n",
  19660. "\n",
  19661. " this._init_header(this);\n",
  19662. " this._init_canvas(this);\n",
  19663. " this._init_toolbar(this);\n",
  19664. "\n",
  19665. " var fig = this;\n",
  19666. "\n",
  19667. " this.waiting = false;\n",
  19668. "\n",
  19669. " this.ws.onopen = function () {\n",
  19670. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  19671. " fig.send_message(\"send_image_mode\", {});\n",
  19672. " if (mpl.ratio != 1) {\n",
  19673. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  19674. " }\n",
  19675. " fig.send_message(\"refresh\", {});\n",
  19676. " }\n",
  19677. "\n",
  19678. " this.imageObj.onload = function() {\n",
  19679. " if (fig.image_mode == 'full') {\n",
  19680. " // Full images could contain transparency (where diff images\n",
  19681. " // almost always do), so we need to clear the canvas so that\n",
  19682. " // there is no ghosting.\n",
  19683. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  19684. " }\n",
  19685. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  19686. " };\n",
  19687. "\n",
  19688. " this.imageObj.onunload = function() {\n",
  19689. " fig.ws.close();\n",
  19690. " }\n",
  19691. "\n",
  19692. " this.ws.onmessage = this._make_on_message_function(this);\n",
  19693. "\n",
  19694. " this.ondownload = ondownload;\n",
  19695. "}\n",
  19696. "\n",
  19697. "mpl.figure.prototype._init_header = function() {\n",
  19698. " var titlebar = $(\n",
  19699. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  19700. " 'ui-helper-clearfix\"/>');\n",
  19701. " var titletext = $(\n",
  19702. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  19703. " 'text-align: center; padding: 3px;\"/>');\n",
  19704. " titlebar.append(titletext)\n",
  19705. " this.root.append(titlebar);\n",
  19706. " this.header = titletext[0];\n",
  19707. "}\n",
  19708. "\n",
  19709. "\n",
  19710. "\n",
  19711. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  19712. "\n",
  19713. "}\n",
  19714. "\n",
  19715. "\n",
  19716. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  19717. "\n",
  19718. "}\n",
  19719. "\n",
  19720. "mpl.figure.prototype._init_canvas = function() {\n",
  19721. " var fig = this;\n",
  19722. "\n",
  19723. " var canvas_div = $('<div/>');\n",
  19724. "\n",
  19725. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  19726. "\n",
  19727. " function canvas_keyboard_event(event) {\n",
  19728. " return fig.key_event(event, event['data']);\n",
  19729. " }\n",
  19730. "\n",
  19731. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  19732. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  19733. " this.canvas_div = canvas_div\n",
  19734. " this._canvas_extra_style(canvas_div)\n",
  19735. " this.root.append(canvas_div);\n",
  19736. "\n",
  19737. " var canvas = $('<canvas/>');\n",
  19738. " canvas.addClass('mpl-canvas');\n",
  19739. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  19740. "\n",
  19741. " this.canvas = canvas[0];\n",
  19742. " this.context = canvas[0].getContext(\"2d\");\n",
  19743. "\n",
  19744. " var backingStore = this.context.backingStorePixelRatio ||\n",
  19745. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  19746. "\tthis.context.mozBackingStorePixelRatio ||\n",
  19747. "\tthis.context.msBackingStorePixelRatio ||\n",
  19748. "\tthis.context.oBackingStorePixelRatio ||\n",
  19749. "\tthis.context.backingStorePixelRatio || 1;\n",
  19750. "\n",
  19751. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  19752. "\n",
  19753. " var rubberband = $('<canvas/>');\n",
  19754. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  19755. "\n",
  19756. " var pass_mouse_events = true;\n",
  19757. "\n",
  19758. " canvas_div.resizable({\n",
  19759. " start: function(event, ui) {\n",
  19760. " pass_mouse_events = false;\n",
  19761. " },\n",
  19762. " resize: function(event, ui) {\n",
  19763. " fig.request_resize(ui.size.width, ui.size.height);\n",
  19764. " },\n",
  19765. " stop: function(event, ui) {\n",
  19766. " pass_mouse_events = true;\n",
  19767. " fig.request_resize(ui.size.width, ui.size.height);\n",
  19768. " },\n",
  19769. " });\n",
  19770. "\n",
  19771. " function mouse_event_fn(event) {\n",
  19772. " if (pass_mouse_events)\n",
  19773. " return fig.mouse_event(event, event['data']);\n",
  19774. " }\n",
  19775. "\n",
  19776. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  19777. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  19778. " // Throttle sequential mouse events to 1 every 20ms.\n",
  19779. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  19780. "\n",
  19781. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  19782. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  19783. "\n",
  19784. " canvas_div.on(\"wheel\", function (event) {\n",
  19785. " event = event.originalEvent;\n",
  19786. " event['data'] = 'scroll'\n",
  19787. " if (event.deltaY < 0) {\n",
  19788. " event.step = 1;\n",
  19789. " } else {\n",
  19790. " event.step = -1;\n",
  19791. " }\n",
  19792. " mouse_event_fn(event);\n",
  19793. " });\n",
  19794. "\n",
  19795. " canvas_div.append(canvas);\n",
  19796. " canvas_div.append(rubberband);\n",
  19797. "\n",
  19798. " this.rubberband = rubberband;\n",
  19799. " this.rubberband_canvas = rubberband[0];\n",
  19800. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  19801. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  19802. "\n",
  19803. " this._resize_canvas = function(width, height) {\n",
  19804. " // Keep the size of the canvas, canvas container, and rubber band\n",
  19805. " // canvas in synch.\n",
  19806. " canvas_div.css('width', width)\n",
  19807. " canvas_div.css('height', height)\n",
  19808. "\n",
  19809. " canvas.attr('width', width * mpl.ratio);\n",
  19810. " canvas.attr('height', height * mpl.ratio);\n",
  19811. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  19812. "\n",
  19813. " rubberband.attr('width', width);\n",
  19814. " rubberband.attr('height', height);\n",
  19815. " }\n",
  19816. "\n",
  19817. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  19818. " // upon first draw.\n",
  19819. " this._resize_canvas(600, 600);\n",
  19820. "\n",
  19821. " // Disable right mouse context menu.\n",
  19822. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  19823. " return false;\n",
  19824. " });\n",
  19825. "\n",
  19826. " function set_focus () {\n",
  19827. " canvas.focus();\n",
  19828. " canvas_div.focus();\n",
  19829. " }\n",
  19830. "\n",
  19831. " window.setTimeout(set_focus, 100);\n",
  19832. "}\n",
  19833. "\n",
  19834. "mpl.figure.prototype._init_toolbar = function() {\n",
  19835. " var fig = this;\n",
  19836. "\n",
  19837. " var nav_element = $('<div/>')\n",
  19838. " nav_element.attr('style', 'width: 100%');\n",
  19839. " this.root.append(nav_element);\n",
  19840. "\n",
  19841. " // Define a callback function for later on.\n",
  19842. " function toolbar_event(event) {\n",
  19843. " return fig.toolbar_button_onclick(event['data']);\n",
  19844. " }\n",
  19845. " function toolbar_mouse_event(event) {\n",
  19846. " return fig.toolbar_button_onmouseover(event['data']);\n",
  19847. " }\n",
  19848. "\n",
  19849. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  19850. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  19851. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  19852. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  19853. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  19854. "\n",
  19855. " if (!name) {\n",
  19856. " // put a spacer in here.\n",
  19857. " continue;\n",
  19858. " }\n",
  19859. " var button = $('<button/>');\n",
  19860. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  19861. " 'ui-button-icon-only');\n",
  19862. " button.attr('role', 'button');\n",
  19863. " button.attr('aria-disabled', 'false');\n",
  19864. " button.click(method_name, toolbar_event);\n",
  19865. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  19866. "\n",
  19867. " var icon_img = $('<span/>');\n",
  19868. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  19869. " icon_img.addClass(image);\n",
  19870. " icon_img.addClass('ui-corner-all');\n",
  19871. "\n",
  19872. " var tooltip_span = $('<span/>');\n",
  19873. " tooltip_span.addClass('ui-button-text');\n",
  19874. " tooltip_span.html(tooltip);\n",
  19875. "\n",
  19876. " button.append(icon_img);\n",
  19877. " button.append(tooltip_span);\n",
  19878. "\n",
  19879. " nav_element.append(button);\n",
  19880. " }\n",
  19881. "\n",
  19882. " var fmt_picker_span = $('<span/>');\n",
  19883. "\n",
  19884. " var fmt_picker = $('<select/>');\n",
  19885. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  19886. " fmt_picker_span.append(fmt_picker);\n",
  19887. " nav_element.append(fmt_picker_span);\n",
  19888. " this.format_dropdown = fmt_picker[0];\n",
  19889. "\n",
  19890. " for (var ind in mpl.extensions) {\n",
  19891. " var fmt = mpl.extensions[ind];\n",
  19892. " var option = $(\n",
  19893. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  19894. " fmt_picker.append(option)\n",
  19895. " }\n",
  19896. "\n",
  19897. " // Add hover states to the ui-buttons\n",
  19898. " $( \".ui-button\" ).hover(\n",
  19899. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  19900. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  19901. " );\n",
  19902. "\n",
  19903. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  19904. " nav_element.append(status_bar);\n",
  19905. " this.message = status_bar[0];\n",
  19906. "}\n",
  19907. "\n",
  19908. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  19909. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  19910. " // which will in turn request a refresh of the image.\n",
  19911. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  19912. "}\n",
  19913. "\n",
  19914. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  19915. " properties['type'] = type;\n",
  19916. " properties['figure_id'] = this.id;\n",
  19917. " this.ws.send(JSON.stringify(properties));\n",
  19918. "}\n",
  19919. "\n",
  19920. "mpl.figure.prototype.send_draw_message = function() {\n",
  19921. " if (!this.waiting) {\n",
  19922. " this.waiting = true;\n",
  19923. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  19924. " }\n",
  19925. "}\n",
  19926. "\n",
  19927. "\n",
  19928. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  19929. " var format_dropdown = fig.format_dropdown;\n",
  19930. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  19931. " fig.ondownload(fig, format);\n",
  19932. "}\n",
  19933. "\n",
  19934. "\n",
  19935. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  19936. " var size = msg['size'];\n",
  19937. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  19938. " fig._resize_canvas(size[0], size[1]);\n",
  19939. " fig.send_message(\"refresh\", {});\n",
  19940. " };\n",
  19941. "}\n",
  19942. "\n",
  19943. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  19944. " var x0 = msg['x0'] / mpl.ratio;\n",
  19945. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  19946. " var x1 = msg['x1'] / mpl.ratio;\n",
  19947. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  19948. " x0 = Math.floor(x0) + 0.5;\n",
  19949. " y0 = Math.floor(y0) + 0.5;\n",
  19950. " x1 = Math.floor(x1) + 0.5;\n",
  19951. " y1 = Math.floor(y1) + 0.5;\n",
  19952. " var min_x = Math.min(x0, x1);\n",
  19953. " var min_y = Math.min(y0, y1);\n",
  19954. " var width = Math.abs(x1 - x0);\n",
  19955. " var height = Math.abs(y1 - y0);\n",
  19956. "\n",
  19957. " fig.rubberband_context.clearRect(\n",
  19958. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  19959. "\n",
  19960. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  19961. "}\n",
  19962. "\n",
  19963. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  19964. " // Updates the figure title.\n",
  19965. " fig.header.textContent = msg['label'];\n",
  19966. "}\n",
  19967. "\n",
  19968. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  19969. " var cursor = msg['cursor'];\n",
  19970. " switch(cursor)\n",
  19971. " {\n",
  19972. " case 0:\n",
  19973. " cursor = 'pointer';\n",
  19974. " break;\n",
  19975. " case 1:\n",
  19976. " cursor = 'default';\n",
  19977. " break;\n",
  19978. " case 2:\n",
  19979. " cursor = 'crosshair';\n",
  19980. " break;\n",
  19981. " case 3:\n",
  19982. " cursor = 'move';\n",
  19983. " break;\n",
  19984. " }\n",
  19985. " fig.rubberband_canvas.style.cursor = cursor;\n",
  19986. "}\n",
  19987. "\n",
  19988. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  19989. " fig.message.textContent = msg['message'];\n",
  19990. "}\n",
  19991. "\n",
  19992. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  19993. " // Request the server to send over a new figure.\n",
  19994. " fig.send_draw_message();\n",
  19995. "}\n",
  19996. "\n",
  19997. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  19998. " fig.image_mode = msg['mode'];\n",
  19999. "}\n",
  20000. "\n",
  20001. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  20002. " // Called whenever the canvas gets updated.\n",
  20003. " this.send_message(\"ack\", {});\n",
  20004. "}\n",
  20005. "\n",
  20006. "// A function to construct a web socket function for onmessage handling.\n",
  20007. "// Called in the figure constructor.\n",
  20008. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  20009. " return function socket_on_message(evt) {\n",
  20010. " if (evt.data instanceof Blob) {\n",
  20011. " /* FIXME: We get \"Resource interpreted as Image but\n",
  20012. " * transferred with MIME type text/plain:\" errors on\n",
  20013. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  20014. " * to be part of the websocket stream */\n",
  20015. " evt.data.type = \"image/png\";\n",
  20016. "\n",
  20017. " /* Free the memory for the previous frames */\n",
  20018. " if (fig.imageObj.src) {\n",
  20019. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  20020. " fig.imageObj.src);\n",
  20021. " }\n",
  20022. "\n",
  20023. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  20024. " evt.data);\n",
  20025. " fig.updated_canvas_event();\n",
  20026. " fig.waiting = false;\n",
  20027. " return;\n",
  20028. " }\n",
  20029. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  20030. " fig.imageObj.src = evt.data;\n",
  20031. " fig.updated_canvas_event();\n",
  20032. " fig.waiting = false;\n",
  20033. " return;\n",
  20034. " }\n",
  20035. "\n",
  20036. " var msg = JSON.parse(evt.data);\n",
  20037. " var msg_type = msg['type'];\n",
  20038. "\n",
  20039. " // Call the \"handle_{type}\" callback, which takes\n",
  20040. " // the figure and JSON message as its only arguments.\n",
  20041. " try {\n",
  20042. " var callback = fig[\"handle_\" + msg_type];\n",
  20043. " } catch (e) {\n",
  20044. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  20045. " return;\n",
  20046. " }\n",
  20047. "\n",
  20048. " if (callback) {\n",
  20049. " try {\n",
  20050. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  20051. " callback(fig, msg);\n",
  20052. " } catch (e) {\n",
  20053. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  20054. " }\n",
  20055. " }\n",
  20056. " };\n",
  20057. "}\n",
  20058. "\n",
  20059. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  20060. "mpl.findpos = function(e) {\n",
  20061. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  20062. " var targ;\n",
  20063. " if (!e)\n",
  20064. " e = window.event;\n",
  20065. " if (e.target)\n",
  20066. " targ = e.target;\n",
  20067. " else if (e.srcElement)\n",
  20068. " targ = e.srcElement;\n",
  20069. " if (targ.nodeType == 3) // defeat Safari bug\n",
  20070. " targ = targ.parentNode;\n",
  20071. "\n",
  20072. " // jQuery normalizes the pageX and pageY\n",
  20073. " // pageX,Y are the mouse positions relative to the document\n",
  20074. " // offset() returns the position of the element relative to the document\n",
  20075. " var x = e.pageX - $(targ).offset().left;\n",
  20076. " var y = e.pageY - $(targ).offset().top;\n",
  20077. "\n",
  20078. " return {\"x\": x, \"y\": y};\n",
  20079. "};\n",
  20080. "\n",
  20081. "/*\n",
  20082. " * return a copy of an object with only non-object keys\n",
  20083. " * we need this to avoid circular references\n",
  20084. " * http://stackoverflow.com/a/24161582/3208463\n",
  20085. " */\n",
  20086. "function simpleKeys (original) {\n",
  20087. " return Object.keys(original).reduce(function (obj, key) {\n",
  20088. " if (typeof original[key] !== 'object')\n",
  20089. " obj[key] = original[key]\n",
  20090. " return obj;\n",
  20091. " }, {});\n",
  20092. "}\n",
  20093. "\n",
  20094. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  20095. " var canvas_pos = mpl.findpos(event)\n",
  20096. "\n",
  20097. " if (name === 'button_press')\n",
  20098. " {\n",
  20099. " this.canvas.focus();\n",
  20100. " this.canvas_div.focus();\n",
  20101. " }\n",
  20102. "\n",
  20103. " var x = canvas_pos.x * mpl.ratio;\n",
  20104. " var y = canvas_pos.y * mpl.ratio;\n",
  20105. "\n",
  20106. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  20107. " step: event.step,\n",
  20108. " guiEvent: simpleKeys(event)});\n",
  20109. "\n",
  20110. " /* This prevents the web browser from automatically changing to\n",
  20111. " * the text insertion cursor when the button is pressed. We want\n",
  20112. " * to control all of the cursor setting manually through the\n",
  20113. " * 'cursor' event from matplotlib */\n",
  20114. " event.preventDefault();\n",
  20115. " return false;\n",
  20116. "}\n",
  20117. "\n",
  20118. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  20119. " // Handle any extra behaviour associated with a key event\n",
  20120. "}\n",
  20121. "\n",
  20122. "mpl.figure.prototype.key_event = function(event, name) {\n",
  20123. "\n",
  20124. " // Prevent repeat events\n",
  20125. " if (name == 'key_press')\n",
  20126. " {\n",
  20127. " if (event.which === this._key)\n",
  20128. " return;\n",
  20129. " else\n",
  20130. " this._key = event.which;\n",
  20131. " }\n",
  20132. " if (name == 'key_release')\n",
  20133. " this._key = null;\n",
  20134. "\n",
  20135. " var value = '';\n",
  20136. " if (event.ctrlKey && event.which != 17)\n",
  20137. " value += \"ctrl+\";\n",
  20138. " if (event.altKey && event.which != 18)\n",
  20139. " value += \"alt+\";\n",
  20140. " if (event.shiftKey && event.which != 16)\n",
  20141. " value += \"shift+\";\n",
  20142. "\n",
  20143. " value += 'k';\n",
  20144. " value += event.which.toString();\n",
  20145. "\n",
  20146. " this._key_event_extra(event, name);\n",
  20147. "\n",
  20148. " this.send_message(name, {key: value,\n",
  20149. " guiEvent: simpleKeys(event)});\n",
  20150. " return false;\n",
  20151. "}\n",
  20152. "\n",
  20153. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  20154. " if (name == 'download') {\n",
  20155. " this.handle_save(this, null);\n",
  20156. " } else {\n",
  20157. " this.send_message(\"toolbar_button\", {name: name});\n",
  20158. " }\n",
  20159. "};\n",
  20160. "\n",
  20161. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  20162. " this.message.textContent = tooltip;\n",
  20163. "};\n",
  20164. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  20165. "\n",
  20166. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  20167. "\n",
  20168. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  20169. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  20170. " // object with the appropriate methods. Currently this is a non binary\n",
  20171. " // socket, so there is still some room for performance tuning.\n",
  20172. " var ws = {};\n",
  20173. "\n",
  20174. " ws.close = function() {\n",
  20175. " comm.close()\n",
  20176. " };\n",
  20177. " ws.send = function(m) {\n",
  20178. " //console.log('sending', m);\n",
  20179. " comm.send(m);\n",
  20180. " };\n",
  20181. " // Register the callback with on_msg.\n",
  20182. " comm.on_msg(function(msg) {\n",
  20183. " //console.log('receiving', msg['content']['data'], msg);\n",
  20184. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  20185. " ws.onmessage(msg['content']['data'])\n",
  20186. " });\n",
  20187. " return ws;\n",
  20188. "}\n",
  20189. "\n",
  20190. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  20191. " // This is the function which gets called when the mpl process\n",
  20192. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  20193. "\n",
  20194. " var id = msg.content.data.id;\n",
  20195. " // Get hold of the div created by the display call when the Comm\n",
  20196. " // socket was opened in Python.\n",
  20197. " var element = $(\"#\" + id);\n",
  20198. " var ws_proxy = comm_websocket_adapter(comm)\n",
  20199. "\n",
  20200. " function ondownload(figure, format) {\n",
  20201. " window.open(figure.imageObj.src);\n",
  20202. " }\n",
  20203. "\n",
  20204. " var fig = new mpl.figure(id, ws_proxy,\n",
  20205. " ondownload,\n",
  20206. " element.get(0));\n",
  20207. "\n",
  20208. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  20209. " // web socket which is closed, not our websocket->open comm proxy.\n",
  20210. " ws_proxy.onopen();\n",
  20211. "\n",
  20212. " fig.parent_element = element.get(0);\n",
  20213. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  20214. " if (!fig.cell_info) {\n",
  20215. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  20216. " return;\n",
  20217. " }\n",
  20218. "\n",
  20219. " var output_index = fig.cell_info[2]\n",
  20220. " var cell = fig.cell_info[0];\n",
  20221. "\n",
  20222. "};\n",
  20223. "\n",
  20224. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  20225. " var width = fig.canvas.width/mpl.ratio\n",
  20226. " fig.root.unbind('remove')\n",
  20227. "\n",
  20228. " // Update the output cell to use the data from the current canvas.\n",
  20229. " fig.push_to_output();\n",
  20230. " var dataURL = fig.canvas.toDataURL();\n",
  20231. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  20232. " // the notebook keyboard shortcuts fail.\n",
  20233. " IPython.keyboard_manager.enable()\n",
  20234. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  20235. " fig.close_ws(fig, msg);\n",
  20236. "}\n",
  20237. "\n",
  20238. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  20239. " fig.send_message('closing', msg);\n",
  20240. " // fig.ws.close()\n",
  20241. "}\n",
  20242. "\n",
  20243. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  20244. " // Turn the data on the canvas into data in the output cell.\n",
  20245. " var width = this.canvas.width/mpl.ratio\n",
  20246. " var dataURL = this.canvas.toDataURL();\n",
  20247. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  20248. "}\n",
  20249. "\n",
  20250. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  20251. " // Tell IPython that the notebook contents must change.\n",
  20252. " IPython.notebook.set_dirty(true);\n",
  20253. " this.send_message(\"ack\", {});\n",
  20254. " var fig = this;\n",
  20255. " // Wait a second, then push the new image to the DOM so\n",
  20256. " // that it is saved nicely (might be nice to debounce this).\n",
  20257. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  20258. "}\n",
  20259. "\n",
  20260. "mpl.figure.prototype._init_toolbar = function() {\n",
  20261. " var fig = this;\n",
  20262. "\n",
  20263. " var nav_element = $('<div/>')\n",
  20264. " nav_element.attr('style', 'width: 100%');\n",
  20265. " this.root.append(nav_element);\n",
  20266. "\n",
  20267. " // Define a callback function for later on.\n",
  20268. " function toolbar_event(event) {\n",
  20269. " return fig.toolbar_button_onclick(event['data']);\n",
  20270. " }\n",
  20271. " function toolbar_mouse_event(event) {\n",
  20272. " return fig.toolbar_button_onmouseover(event['data']);\n",
  20273. " }\n",
  20274. "\n",
  20275. " for(var toolbar_ind in mpl.toolbar_items){\n",
  20276. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  20277. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  20278. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  20279. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  20280. "\n",
  20281. " if (!name) { continue; };\n",
  20282. "\n",
  20283. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  20284. " button.click(method_name, toolbar_event);\n",
  20285. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  20286. " nav_element.append(button);\n",
  20287. " }\n",
  20288. "\n",
  20289. " // Add the status bar.\n",
  20290. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  20291. " nav_element.append(status_bar);\n",
  20292. " this.message = status_bar[0];\n",
  20293. "\n",
  20294. " // Add the close button to the window.\n",
  20295. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  20296. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  20297. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  20298. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  20299. " buttongrp.append(button);\n",
  20300. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  20301. " titlebar.prepend(buttongrp);\n",
  20302. "}\n",
  20303. "\n",
  20304. "mpl.figure.prototype._root_extra_style = function(el){\n",
  20305. " var fig = this\n",
  20306. " el.on(\"remove\", function(){\n",
  20307. "\tfig.close_ws(fig, {});\n",
  20308. " });\n",
  20309. "}\n",
  20310. "\n",
  20311. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  20312. " // this is important to make the div 'focusable\n",
  20313. " el.attr('tabindex', 0)\n",
  20314. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  20315. " // off when our div gets focus\n",
  20316. "\n",
  20317. " // location in version 3\n",
  20318. " if (IPython.notebook.keyboard_manager) {\n",
  20319. " IPython.notebook.keyboard_manager.register_events(el);\n",
  20320. " }\n",
  20321. " else {\n",
  20322. " // location in version 2\n",
  20323. " IPython.keyboard_manager.register_events(el);\n",
  20324. " }\n",
  20325. "\n",
  20326. "}\n",
  20327. "\n",
  20328. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  20329. " var manager = IPython.notebook.keyboard_manager;\n",
  20330. " if (!manager)\n",
  20331. " manager = IPython.keyboard_manager;\n",
  20332. "\n",
  20333. " // Check for shift+enter\n",
  20334. " if (event.shiftKey && event.which == 13) {\n",
  20335. " this.canvas_div.blur();\n",
  20336. " event.shiftKey = false;\n",
  20337. " // Send a \"J\" for go to next cell\n",
  20338. " event.which = 74;\n",
  20339. " event.keyCode = 74;\n",
  20340. " manager.command_mode();\n",
  20341. " manager.handle_keydown(event);\n",
  20342. " }\n",
  20343. "}\n",
  20344. "\n",
  20345. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  20346. " fig.ondownload(fig, null);\n",
  20347. "}\n",
  20348. "\n",
  20349. "\n",
  20350. "mpl.find_output_cell = function(html_output) {\n",
  20351. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  20352. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  20353. " // IPython event is triggered only after the cells have been serialised, which for\n",
  20354. " // our purposes (turning an active figure into a static one), is too late.\n",
  20355. " var cells = IPython.notebook.get_cells();\n",
  20356. " var ncells = cells.length;\n",
  20357. " for (var i=0; i<ncells; i++) {\n",
  20358. " var cell = cells[i];\n",
  20359. " if (cell.cell_type === 'code'){\n",
  20360. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  20361. " var data = cell.output_area.outputs[j];\n",
  20362. " if (data.data) {\n",
  20363. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  20364. " data = data.data;\n",
  20365. " }\n",
  20366. " if (data['text/html'] == html_output) {\n",
  20367. " return [cell, data, j];\n",
  20368. " }\n",
  20369. " }\n",
  20370. " }\n",
  20371. " }\n",
  20372. "}\n",
  20373. "\n",
  20374. "// Register the function which deals with the matplotlib target/channel.\n",
  20375. "// The kernel may be null if the page has been refreshed.\n",
  20376. "if (IPython.notebook.kernel != null) {\n",
  20377. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  20378. "}\n"
  20379. ],
  20380. "text/plain": [
  20381. "<IPython.core.display.Javascript object>"
  20382. ]
  20383. },
  20384. "metadata": {},
  20385. "output_type": "display_data"
  20386. },
  20387. {
  20388. "data": {
  20389. "text/html": [
  20390. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  20391. ],
  20392. "text/plain": [
  20393. "<IPython.core.display.HTML object>"
  20394. ]
  20395. },
  20396. "metadata": {},
  20397. "output_type": "display_data"
  20398. },
  20399. {
  20400. "name": "stdout",
  20401. "output_type": "stream",
  20402. "text": [
  20403. "0.0 0.99966\n",
  20404. "268.25858\n",
  20405. "(366, 318)\n",
  20406. "\n"
  20407. ]
  20408. },
  20409. {
  20410. "data": {
  20411. "application/javascript": [
  20412. "/* Put everything inside the global mpl namespace */\n",
  20413. "window.mpl = {};\n",
  20414. "\n",
  20415. "\n",
  20416. "mpl.get_websocket_type = function() {\n",
  20417. " if (typeof(WebSocket) !== 'undefined') {\n",
  20418. " return WebSocket;\n",
  20419. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  20420. " return MozWebSocket;\n",
  20421. " } else {\n",
  20422. " alert('Your browser does not have WebSocket support.' +\n",
  20423. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  20424. " 'Firefox 4 and 5 are also supported but you ' +\n",
  20425. " 'have to enable WebSockets in about:config.');\n",
  20426. " };\n",
  20427. "}\n",
  20428. "\n",
  20429. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  20430. " this.id = figure_id;\n",
  20431. "\n",
  20432. " this.ws = websocket;\n",
  20433. "\n",
  20434. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  20435. "\n",
  20436. " if (!this.supports_binary) {\n",
  20437. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  20438. " if (warnings) {\n",
  20439. " warnings.style.display = 'block';\n",
  20440. " warnings.textContent = (\n",
  20441. " \"This browser does not support binary websocket messages. \" +\n",
  20442. " \"Performance may be slow.\");\n",
  20443. " }\n",
  20444. " }\n",
  20445. "\n",
  20446. " this.imageObj = new Image();\n",
  20447. "\n",
  20448. " this.context = undefined;\n",
  20449. " this.message = undefined;\n",
  20450. " this.canvas = undefined;\n",
  20451. " this.rubberband_canvas = undefined;\n",
  20452. " this.rubberband_context = undefined;\n",
  20453. " this.format_dropdown = undefined;\n",
  20454. "\n",
  20455. " this.image_mode = 'full';\n",
  20456. "\n",
  20457. " this.root = $('<div/>');\n",
  20458. " this._root_extra_style(this.root)\n",
  20459. " this.root.attr('style', 'display: inline-block');\n",
  20460. "\n",
  20461. " $(parent_element).append(this.root);\n",
  20462. "\n",
  20463. " this._init_header(this);\n",
  20464. " this._init_canvas(this);\n",
  20465. " this._init_toolbar(this);\n",
  20466. "\n",
  20467. " var fig = this;\n",
  20468. "\n",
  20469. " this.waiting = false;\n",
  20470. "\n",
  20471. " this.ws.onopen = function () {\n",
  20472. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  20473. " fig.send_message(\"send_image_mode\", {});\n",
  20474. " if (mpl.ratio != 1) {\n",
  20475. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  20476. " }\n",
  20477. " fig.send_message(\"refresh\", {});\n",
  20478. " }\n",
  20479. "\n",
  20480. " this.imageObj.onload = function() {\n",
  20481. " if (fig.image_mode == 'full') {\n",
  20482. " // Full images could contain transparency (where diff images\n",
  20483. " // almost always do), so we need to clear the canvas so that\n",
  20484. " // there is no ghosting.\n",
  20485. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  20486. " }\n",
  20487. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  20488. " };\n",
  20489. "\n",
  20490. " this.imageObj.onunload = function() {\n",
  20491. " fig.ws.close();\n",
  20492. " }\n",
  20493. "\n",
  20494. " this.ws.onmessage = this._make_on_message_function(this);\n",
  20495. "\n",
  20496. " this.ondownload = ondownload;\n",
  20497. "}\n",
  20498. "\n",
  20499. "mpl.figure.prototype._init_header = function() {\n",
  20500. " var titlebar = $(\n",
  20501. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  20502. " 'ui-helper-clearfix\"/>');\n",
  20503. " var titletext = $(\n",
  20504. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  20505. " 'text-align: center; padding: 3px;\"/>');\n",
  20506. " titlebar.append(titletext)\n",
  20507. " this.root.append(titlebar);\n",
  20508. " this.header = titletext[0];\n",
  20509. "}\n",
  20510. "\n",
  20511. "\n",
  20512. "\n",
  20513. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  20514. "\n",
  20515. "}\n",
  20516. "\n",
  20517. "\n",
  20518. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  20519. "\n",
  20520. "}\n",
  20521. "\n",
  20522. "mpl.figure.prototype._init_canvas = function() {\n",
  20523. " var fig = this;\n",
  20524. "\n",
  20525. " var canvas_div = $('<div/>');\n",
  20526. "\n",
  20527. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  20528. "\n",
  20529. " function canvas_keyboard_event(event) {\n",
  20530. " return fig.key_event(event, event['data']);\n",
  20531. " }\n",
  20532. "\n",
  20533. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  20534. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  20535. " this.canvas_div = canvas_div\n",
  20536. " this._canvas_extra_style(canvas_div)\n",
  20537. " this.root.append(canvas_div);\n",
  20538. "\n",
  20539. " var canvas = $('<canvas/>');\n",
  20540. " canvas.addClass('mpl-canvas');\n",
  20541. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  20542. "\n",
  20543. " this.canvas = canvas[0];\n",
  20544. " this.context = canvas[0].getContext(\"2d\");\n",
  20545. "\n",
  20546. " var backingStore = this.context.backingStorePixelRatio ||\n",
  20547. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  20548. "\tthis.context.mozBackingStorePixelRatio ||\n",
  20549. "\tthis.context.msBackingStorePixelRatio ||\n",
  20550. "\tthis.context.oBackingStorePixelRatio ||\n",
  20551. "\tthis.context.backingStorePixelRatio || 1;\n",
  20552. "\n",
  20553. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  20554. "\n",
  20555. " var rubberband = $('<canvas/>');\n",
  20556. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  20557. "\n",
  20558. " var pass_mouse_events = true;\n",
  20559. "\n",
  20560. " canvas_div.resizable({\n",
  20561. " start: function(event, ui) {\n",
  20562. " pass_mouse_events = false;\n",
  20563. " },\n",
  20564. " resize: function(event, ui) {\n",
  20565. " fig.request_resize(ui.size.width, ui.size.height);\n",
  20566. " },\n",
  20567. " stop: function(event, ui) {\n",
  20568. " pass_mouse_events = true;\n",
  20569. " fig.request_resize(ui.size.width, ui.size.height);\n",
  20570. " },\n",
  20571. " });\n",
  20572. "\n",
  20573. " function mouse_event_fn(event) {\n",
  20574. " if (pass_mouse_events)\n",
  20575. " return fig.mouse_event(event, event['data']);\n",
  20576. " }\n",
  20577. "\n",
  20578. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  20579. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  20580. " // Throttle sequential mouse events to 1 every 20ms.\n",
  20581. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  20582. "\n",
  20583. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  20584. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  20585. "\n",
  20586. " canvas_div.on(\"wheel\", function (event) {\n",
  20587. " event = event.originalEvent;\n",
  20588. " event['data'] = 'scroll'\n",
  20589. " if (event.deltaY < 0) {\n",
  20590. " event.step = 1;\n",
  20591. " } else {\n",
  20592. " event.step = -1;\n",
  20593. " }\n",
  20594. " mouse_event_fn(event);\n",
  20595. " });\n",
  20596. "\n",
  20597. " canvas_div.append(canvas);\n",
  20598. " canvas_div.append(rubberband);\n",
  20599. "\n",
  20600. " this.rubberband = rubberband;\n",
  20601. " this.rubberband_canvas = rubberband[0];\n",
  20602. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  20603. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  20604. "\n",
  20605. " this._resize_canvas = function(width, height) {\n",
  20606. " // Keep the size of the canvas, canvas container, and rubber band\n",
  20607. " // canvas in synch.\n",
  20608. " canvas_div.css('width', width)\n",
  20609. " canvas_div.css('height', height)\n",
  20610. "\n",
  20611. " canvas.attr('width', width * mpl.ratio);\n",
  20612. " canvas.attr('height', height * mpl.ratio);\n",
  20613. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  20614. "\n",
  20615. " rubberband.attr('width', width);\n",
  20616. " rubberband.attr('height', height);\n",
  20617. " }\n",
  20618. "\n",
  20619. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  20620. " // upon first draw.\n",
  20621. " this._resize_canvas(600, 600);\n",
  20622. "\n",
  20623. " // Disable right mouse context menu.\n",
  20624. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  20625. " return false;\n",
  20626. " });\n",
  20627. "\n",
  20628. " function set_focus () {\n",
  20629. " canvas.focus();\n",
  20630. " canvas_div.focus();\n",
  20631. " }\n",
  20632. "\n",
  20633. " window.setTimeout(set_focus, 100);\n",
  20634. "}\n",
  20635. "\n",
  20636. "mpl.figure.prototype._init_toolbar = function() {\n",
  20637. " var fig = this;\n",
  20638. "\n",
  20639. " var nav_element = $('<div/>')\n",
  20640. " nav_element.attr('style', 'width: 100%');\n",
  20641. " this.root.append(nav_element);\n",
  20642. "\n",
  20643. " // Define a callback function for later on.\n",
  20644. " function toolbar_event(event) {\n",
  20645. " return fig.toolbar_button_onclick(event['data']);\n",
  20646. " }\n",
  20647. " function toolbar_mouse_event(event) {\n",
  20648. " return fig.toolbar_button_onmouseover(event['data']);\n",
  20649. " }\n",
  20650. "\n",
  20651. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  20652. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  20653. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  20654. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  20655. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  20656. "\n",
  20657. " if (!name) {\n",
  20658. " // put a spacer in here.\n",
  20659. " continue;\n",
  20660. " }\n",
  20661. " var button = $('<button/>');\n",
  20662. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  20663. " 'ui-button-icon-only');\n",
  20664. " button.attr('role', 'button');\n",
  20665. " button.attr('aria-disabled', 'false');\n",
  20666. " button.click(method_name, toolbar_event);\n",
  20667. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  20668. "\n",
  20669. " var icon_img = $('<span/>');\n",
  20670. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  20671. " icon_img.addClass(image);\n",
  20672. " icon_img.addClass('ui-corner-all');\n",
  20673. "\n",
  20674. " var tooltip_span = $('<span/>');\n",
  20675. " tooltip_span.addClass('ui-button-text');\n",
  20676. " tooltip_span.html(tooltip);\n",
  20677. "\n",
  20678. " button.append(icon_img);\n",
  20679. " button.append(tooltip_span);\n",
  20680. "\n",
  20681. " nav_element.append(button);\n",
  20682. " }\n",
  20683. "\n",
  20684. " var fmt_picker_span = $('<span/>');\n",
  20685. "\n",
  20686. " var fmt_picker = $('<select/>');\n",
  20687. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  20688. " fmt_picker_span.append(fmt_picker);\n",
  20689. " nav_element.append(fmt_picker_span);\n",
  20690. " this.format_dropdown = fmt_picker[0];\n",
  20691. "\n",
  20692. " for (var ind in mpl.extensions) {\n",
  20693. " var fmt = mpl.extensions[ind];\n",
  20694. " var option = $(\n",
  20695. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  20696. " fmt_picker.append(option)\n",
  20697. " }\n",
  20698. "\n",
  20699. " // Add hover states to the ui-buttons\n",
  20700. " $( \".ui-button\" ).hover(\n",
  20701. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  20702. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  20703. " );\n",
  20704. "\n",
  20705. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  20706. " nav_element.append(status_bar);\n",
  20707. " this.message = status_bar[0];\n",
  20708. "}\n",
  20709. "\n",
  20710. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  20711. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  20712. " // which will in turn request a refresh of the image.\n",
  20713. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  20714. "}\n",
  20715. "\n",
  20716. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  20717. " properties['type'] = type;\n",
  20718. " properties['figure_id'] = this.id;\n",
  20719. " this.ws.send(JSON.stringify(properties));\n",
  20720. "}\n",
  20721. "\n",
  20722. "mpl.figure.prototype.send_draw_message = function() {\n",
  20723. " if (!this.waiting) {\n",
  20724. " this.waiting = true;\n",
  20725. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  20726. " }\n",
  20727. "}\n",
  20728. "\n",
  20729. "\n",
  20730. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  20731. " var format_dropdown = fig.format_dropdown;\n",
  20732. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  20733. " fig.ondownload(fig, format);\n",
  20734. "}\n",
  20735. "\n",
  20736. "\n",
  20737. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  20738. " var size = msg['size'];\n",
  20739. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  20740. " fig._resize_canvas(size[0], size[1]);\n",
  20741. " fig.send_message(\"refresh\", {});\n",
  20742. " };\n",
  20743. "}\n",
  20744. "\n",
  20745. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  20746. " var x0 = msg['x0'] / mpl.ratio;\n",
  20747. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  20748. " var x1 = msg['x1'] / mpl.ratio;\n",
  20749. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  20750. " x0 = Math.floor(x0) + 0.5;\n",
  20751. " y0 = Math.floor(y0) + 0.5;\n",
  20752. " x1 = Math.floor(x1) + 0.5;\n",
  20753. " y1 = Math.floor(y1) + 0.5;\n",
  20754. " var min_x = Math.min(x0, x1);\n",
  20755. " var min_y = Math.min(y0, y1);\n",
  20756. " var width = Math.abs(x1 - x0);\n",
  20757. " var height = Math.abs(y1 - y0);\n",
  20758. "\n",
  20759. " fig.rubberband_context.clearRect(\n",
  20760. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  20761. "\n",
  20762. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  20763. "}\n",
  20764. "\n",
  20765. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  20766. " // Updates the figure title.\n",
  20767. " fig.header.textContent = msg['label'];\n",
  20768. "}\n",
  20769. "\n",
  20770. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  20771. " var cursor = msg['cursor'];\n",
  20772. " switch(cursor)\n",
  20773. " {\n",
  20774. " case 0:\n",
  20775. " cursor = 'pointer';\n",
  20776. " break;\n",
  20777. " case 1:\n",
  20778. " cursor = 'default';\n",
  20779. " break;\n",
  20780. " case 2:\n",
  20781. " cursor = 'crosshair';\n",
  20782. " break;\n",
  20783. " case 3:\n",
  20784. " cursor = 'move';\n",
  20785. " break;\n",
  20786. " }\n",
  20787. " fig.rubberband_canvas.style.cursor = cursor;\n",
  20788. "}\n",
  20789. "\n",
  20790. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  20791. " fig.message.textContent = msg['message'];\n",
  20792. "}\n",
  20793. "\n",
  20794. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  20795. " // Request the server to send over a new figure.\n",
  20796. " fig.send_draw_message();\n",
  20797. "}\n",
  20798. "\n",
  20799. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  20800. " fig.image_mode = msg['mode'];\n",
  20801. "}\n",
  20802. "\n",
  20803. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  20804. " // Called whenever the canvas gets updated.\n",
  20805. " this.send_message(\"ack\", {});\n",
  20806. "}\n",
  20807. "\n",
  20808. "// A function to construct a web socket function for onmessage handling.\n",
  20809. "// Called in the figure constructor.\n",
  20810. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  20811. " return function socket_on_message(evt) {\n",
  20812. " if (evt.data instanceof Blob) {\n",
  20813. " /* FIXME: We get \"Resource interpreted as Image but\n",
  20814. " * transferred with MIME type text/plain:\" errors on\n",
  20815. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  20816. " * to be part of the websocket stream */\n",
  20817. " evt.data.type = \"image/png\";\n",
  20818. "\n",
  20819. " /* Free the memory for the previous frames */\n",
  20820. " if (fig.imageObj.src) {\n",
  20821. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  20822. " fig.imageObj.src);\n",
  20823. " }\n",
  20824. "\n",
  20825. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  20826. " evt.data);\n",
  20827. " fig.updated_canvas_event();\n",
  20828. " fig.waiting = false;\n",
  20829. " return;\n",
  20830. " }\n",
  20831. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  20832. " fig.imageObj.src = evt.data;\n",
  20833. " fig.updated_canvas_event();\n",
  20834. " fig.waiting = false;\n",
  20835. " return;\n",
  20836. " }\n",
  20837. "\n",
  20838. " var msg = JSON.parse(evt.data);\n",
  20839. " var msg_type = msg['type'];\n",
  20840. "\n",
  20841. " // Call the \"handle_{type}\" callback, which takes\n",
  20842. " // the figure and JSON message as its only arguments.\n",
  20843. " try {\n",
  20844. " var callback = fig[\"handle_\" + msg_type];\n",
  20845. " } catch (e) {\n",
  20846. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  20847. " return;\n",
  20848. " }\n",
  20849. "\n",
  20850. " if (callback) {\n",
  20851. " try {\n",
  20852. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  20853. " callback(fig, msg);\n",
  20854. " } catch (e) {\n",
  20855. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  20856. " }\n",
  20857. " }\n",
  20858. " };\n",
  20859. "}\n",
  20860. "\n",
  20861. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  20862. "mpl.findpos = function(e) {\n",
  20863. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  20864. " var targ;\n",
  20865. " if (!e)\n",
  20866. " e = window.event;\n",
  20867. " if (e.target)\n",
  20868. " targ = e.target;\n",
  20869. " else if (e.srcElement)\n",
  20870. " targ = e.srcElement;\n",
  20871. " if (targ.nodeType == 3) // defeat Safari bug\n",
  20872. " targ = targ.parentNode;\n",
  20873. "\n",
  20874. " // jQuery normalizes the pageX and pageY\n",
  20875. " // pageX,Y are the mouse positions relative to the document\n",
  20876. " // offset() returns the position of the element relative to the document\n",
  20877. " var x = e.pageX - $(targ).offset().left;\n",
  20878. " var y = e.pageY - $(targ).offset().top;\n",
  20879. "\n",
  20880. " return {\"x\": x, \"y\": y};\n",
  20881. "};\n",
  20882. "\n",
  20883. "/*\n",
  20884. " * return a copy of an object with only non-object keys\n",
  20885. " * we need this to avoid circular references\n",
  20886. " * http://stackoverflow.com/a/24161582/3208463\n",
  20887. " */\n",
  20888. "function simpleKeys (original) {\n",
  20889. " return Object.keys(original).reduce(function (obj, key) {\n",
  20890. " if (typeof original[key] !== 'object')\n",
  20891. " obj[key] = original[key]\n",
  20892. " return obj;\n",
  20893. " }, {});\n",
  20894. "}\n",
  20895. "\n",
  20896. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  20897. " var canvas_pos = mpl.findpos(event)\n",
  20898. "\n",
  20899. " if (name === 'button_press')\n",
  20900. " {\n",
  20901. " this.canvas.focus();\n",
  20902. " this.canvas_div.focus();\n",
  20903. " }\n",
  20904. "\n",
  20905. " var x = canvas_pos.x * mpl.ratio;\n",
  20906. " var y = canvas_pos.y * mpl.ratio;\n",
  20907. "\n",
  20908. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  20909. " step: event.step,\n",
  20910. " guiEvent: simpleKeys(event)});\n",
  20911. "\n",
  20912. " /* This prevents the web browser from automatically changing to\n",
  20913. " * the text insertion cursor when the button is pressed. We want\n",
  20914. " * to control all of the cursor setting manually through the\n",
  20915. " * 'cursor' event from matplotlib */\n",
  20916. " event.preventDefault();\n",
  20917. " return false;\n",
  20918. "}\n",
  20919. "\n",
  20920. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  20921. " // Handle any extra behaviour associated with a key event\n",
  20922. "}\n",
  20923. "\n",
  20924. "mpl.figure.prototype.key_event = function(event, name) {\n",
  20925. "\n",
  20926. " // Prevent repeat events\n",
  20927. " if (name == 'key_press')\n",
  20928. " {\n",
  20929. " if (event.which === this._key)\n",
  20930. " return;\n",
  20931. " else\n",
  20932. " this._key = event.which;\n",
  20933. " }\n",
  20934. " if (name == 'key_release')\n",
  20935. " this._key = null;\n",
  20936. "\n",
  20937. " var value = '';\n",
  20938. " if (event.ctrlKey && event.which != 17)\n",
  20939. " value += \"ctrl+\";\n",
  20940. " if (event.altKey && event.which != 18)\n",
  20941. " value += \"alt+\";\n",
  20942. " if (event.shiftKey && event.which != 16)\n",
  20943. " value += \"shift+\";\n",
  20944. "\n",
  20945. " value += 'k';\n",
  20946. " value += event.which.toString();\n",
  20947. "\n",
  20948. " this._key_event_extra(event, name);\n",
  20949. "\n",
  20950. " this.send_message(name, {key: value,\n",
  20951. " guiEvent: simpleKeys(event)});\n",
  20952. " return false;\n",
  20953. "}\n",
  20954. "\n",
  20955. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  20956. " if (name == 'download') {\n",
  20957. " this.handle_save(this, null);\n",
  20958. " } else {\n",
  20959. " this.send_message(\"toolbar_button\", {name: name});\n",
  20960. " }\n",
  20961. "};\n",
  20962. "\n",
  20963. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  20964. " this.message.textContent = tooltip;\n",
  20965. "};\n",
  20966. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  20967. "\n",
  20968. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  20969. "\n",
  20970. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  20971. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  20972. " // object with the appropriate methods. Currently this is a non binary\n",
  20973. " // socket, so there is still some room for performance tuning.\n",
  20974. " var ws = {};\n",
  20975. "\n",
  20976. " ws.close = function() {\n",
  20977. " comm.close()\n",
  20978. " };\n",
  20979. " ws.send = function(m) {\n",
  20980. " //console.log('sending', m);\n",
  20981. " comm.send(m);\n",
  20982. " };\n",
  20983. " // Register the callback with on_msg.\n",
  20984. " comm.on_msg(function(msg) {\n",
  20985. " //console.log('receiving', msg['content']['data'], msg);\n",
  20986. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  20987. " ws.onmessage(msg['content']['data'])\n",
  20988. " });\n",
  20989. " return ws;\n",
  20990. "}\n",
  20991. "\n",
  20992. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  20993. " // This is the function which gets called when the mpl process\n",
  20994. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  20995. "\n",
  20996. " var id = msg.content.data.id;\n",
  20997. " // Get hold of the div created by the display call when the Comm\n",
  20998. " // socket was opened in Python.\n",
  20999. " var element = $(\"#\" + id);\n",
  21000. " var ws_proxy = comm_websocket_adapter(comm)\n",
  21001. "\n",
  21002. " function ondownload(figure, format) {\n",
  21003. " window.open(figure.imageObj.src);\n",
  21004. " }\n",
  21005. "\n",
  21006. " var fig = new mpl.figure(id, ws_proxy,\n",
  21007. " ondownload,\n",
  21008. " element.get(0));\n",
  21009. "\n",
  21010. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  21011. " // web socket which is closed, not our websocket->open comm proxy.\n",
  21012. " ws_proxy.onopen();\n",
  21013. "\n",
  21014. " fig.parent_element = element.get(0);\n",
  21015. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  21016. " if (!fig.cell_info) {\n",
  21017. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  21018. " return;\n",
  21019. " }\n",
  21020. "\n",
  21021. " var output_index = fig.cell_info[2]\n",
  21022. " var cell = fig.cell_info[0];\n",
  21023. "\n",
  21024. "};\n",
  21025. "\n",
  21026. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  21027. " var width = fig.canvas.width/mpl.ratio\n",
  21028. " fig.root.unbind('remove')\n",
  21029. "\n",
  21030. " // Update the output cell to use the data from the current canvas.\n",
  21031. " fig.push_to_output();\n",
  21032. " var dataURL = fig.canvas.toDataURL();\n",
  21033. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  21034. " // the notebook keyboard shortcuts fail.\n",
  21035. " IPython.keyboard_manager.enable()\n",
  21036. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  21037. " fig.close_ws(fig, msg);\n",
  21038. "}\n",
  21039. "\n",
  21040. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  21041. " fig.send_message('closing', msg);\n",
  21042. " // fig.ws.close()\n",
  21043. "}\n",
  21044. "\n",
  21045. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  21046. " // Turn the data on the canvas into data in the output cell.\n",
  21047. " var width = this.canvas.width/mpl.ratio\n",
  21048. " var dataURL = this.canvas.toDataURL();\n",
  21049. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  21050. "}\n",
  21051. "\n",
  21052. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  21053. " // Tell IPython that the notebook contents must change.\n",
  21054. " IPython.notebook.set_dirty(true);\n",
  21055. " this.send_message(\"ack\", {});\n",
  21056. " var fig = this;\n",
  21057. " // Wait a second, then push the new image to the DOM so\n",
  21058. " // that it is saved nicely (might be nice to debounce this).\n",
  21059. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  21060. "}\n",
  21061. "\n",
  21062. "mpl.figure.prototype._init_toolbar = function() {\n",
  21063. " var fig = this;\n",
  21064. "\n",
  21065. " var nav_element = $('<div/>')\n",
  21066. " nav_element.attr('style', 'width: 100%');\n",
  21067. " this.root.append(nav_element);\n",
  21068. "\n",
  21069. " // Define a callback function for later on.\n",
  21070. " function toolbar_event(event) {\n",
  21071. " return fig.toolbar_button_onclick(event['data']);\n",
  21072. " }\n",
  21073. " function toolbar_mouse_event(event) {\n",
  21074. " return fig.toolbar_button_onmouseover(event['data']);\n",
  21075. " }\n",
  21076. "\n",
  21077. " for(var toolbar_ind in mpl.toolbar_items){\n",
  21078. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  21079. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  21080. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  21081. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  21082. "\n",
  21083. " if (!name) { continue; };\n",
  21084. "\n",
  21085. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  21086. " button.click(method_name, toolbar_event);\n",
  21087. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  21088. " nav_element.append(button);\n",
  21089. " }\n",
  21090. "\n",
  21091. " // Add the status bar.\n",
  21092. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  21093. " nav_element.append(status_bar);\n",
  21094. " this.message = status_bar[0];\n",
  21095. "\n",
  21096. " // Add the close button to the window.\n",
  21097. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  21098. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  21099. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  21100. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  21101. " buttongrp.append(button);\n",
  21102. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  21103. " titlebar.prepend(buttongrp);\n",
  21104. "}\n",
  21105. "\n",
  21106. "mpl.figure.prototype._root_extra_style = function(el){\n",
  21107. " var fig = this\n",
  21108. " el.on(\"remove\", function(){\n",
  21109. "\tfig.close_ws(fig, {});\n",
  21110. " });\n",
  21111. "}\n",
  21112. "\n",
  21113. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  21114. " // this is important to make the div 'focusable\n",
  21115. " el.attr('tabindex', 0)\n",
  21116. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  21117. " // off when our div gets focus\n",
  21118. "\n",
  21119. " // location in version 3\n",
  21120. " if (IPython.notebook.keyboard_manager) {\n",
  21121. " IPython.notebook.keyboard_manager.register_events(el);\n",
  21122. " }\n",
  21123. " else {\n",
  21124. " // location in version 2\n",
  21125. " IPython.keyboard_manager.register_events(el);\n",
  21126. " }\n",
  21127. "\n",
  21128. "}\n",
  21129. "\n",
  21130. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  21131. " var manager = IPython.notebook.keyboard_manager;\n",
  21132. " if (!manager)\n",
  21133. " manager = IPython.keyboard_manager;\n",
  21134. "\n",
  21135. " // Check for shift+enter\n",
  21136. " if (event.shiftKey && event.which == 13) {\n",
  21137. " this.canvas_div.blur();\n",
  21138. " event.shiftKey = false;\n",
  21139. " // Send a \"J\" for go to next cell\n",
  21140. " event.which = 74;\n",
  21141. " event.keyCode = 74;\n",
  21142. " manager.command_mode();\n",
  21143. " manager.handle_keydown(event);\n",
  21144. " }\n",
  21145. "}\n",
  21146. "\n",
  21147. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  21148. " fig.ondownload(fig, null);\n",
  21149. "}\n",
  21150. "\n",
  21151. "\n",
  21152. "mpl.find_output_cell = function(html_output) {\n",
  21153. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  21154. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  21155. " // IPython event is triggered only after the cells have been serialised, which for\n",
  21156. " // our purposes (turning an active figure into a static one), is too late.\n",
  21157. " var cells = IPython.notebook.get_cells();\n",
  21158. " var ncells = cells.length;\n",
  21159. " for (var i=0; i<ncells; i++) {\n",
  21160. " var cell = cells[i];\n",
  21161. " if (cell.cell_type === 'code'){\n",
  21162. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  21163. " var data = cell.output_area.outputs[j];\n",
  21164. " if (data.data) {\n",
  21165. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  21166. " data = data.data;\n",
  21167. " }\n",
  21168. " if (data['text/html'] == html_output) {\n",
  21169. " return [cell, data, j];\n",
  21170. " }\n",
  21171. " }\n",
  21172. " }\n",
  21173. " }\n",
  21174. "}\n",
  21175. "\n",
  21176. "// Register the function which deals with the matplotlib target/channel.\n",
  21177. "// The kernel may be null if the page has been refreshed.\n",
  21178. "if (IPython.notebook.kernel != null) {\n",
  21179. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  21180. "}\n"
  21181. ],
  21182. "text/plain": [
  21183. "<IPython.core.display.Javascript object>"
  21184. ]
  21185. },
  21186. "metadata": {},
  21187. "output_type": "display_data"
  21188. },
  21189. {
  21190. "data": {
  21191. "text/html": [
  21192. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  21193. ],
  21194. "text/plain": [
  21195. "<IPython.core.display.HTML object>"
  21196. ]
  21197. },
  21198. "metadata": {},
  21199. "output_type": "display_data"
  21200. },
  21201. {
  21202. "name": "stdout",
  21203. "output_type": "stream",
  21204. "text": [
  21205. "-0.22025777 4.047913\n",
  21206. "19420.662\n",
  21207. "(234, 201)\n",
  21208. "\n"
  21209. ]
  21210. },
  21211. {
  21212. "data": {
  21213. "application/javascript": [
  21214. "/* Put everything inside the global mpl namespace */\n",
  21215. "window.mpl = {};\n",
  21216. "\n",
  21217. "\n",
  21218. "mpl.get_websocket_type = function() {\n",
  21219. " if (typeof(WebSocket) !== 'undefined') {\n",
  21220. " return WebSocket;\n",
  21221. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  21222. " return MozWebSocket;\n",
  21223. " } else {\n",
  21224. " alert('Your browser does not have WebSocket support.' +\n",
  21225. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  21226. " 'Firefox 4 and 5 are also supported but you ' +\n",
  21227. " 'have to enable WebSockets in about:config.');\n",
  21228. " };\n",
  21229. "}\n",
  21230. "\n",
  21231. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  21232. " this.id = figure_id;\n",
  21233. "\n",
  21234. " this.ws = websocket;\n",
  21235. "\n",
  21236. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  21237. "\n",
  21238. " if (!this.supports_binary) {\n",
  21239. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  21240. " if (warnings) {\n",
  21241. " warnings.style.display = 'block';\n",
  21242. " warnings.textContent = (\n",
  21243. " \"This browser does not support binary websocket messages. \" +\n",
  21244. " \"Performance may be slow.\");\n",
  21245. " }\n",
  21246. " }\n",
  21247. "\n",
  21248. " this.imageObj = new Image();\n",
  21249. "\n",
  21250. " this.context = undefined;\n",
  21251. " this.message = undefined;\n",
  21252. " this.canvas = undefined;\n",
  21253. " this.rubberband_canvas = undefined;\n",
  21254. " this.rubberband_context = undefined;\n",
  21255. " this.format_dropdown = undefined;\n",
  21256. "\n",
  21257. " this.image_mode = 'full';\n",
  21258. "\n",
  21259. " this.root = $('<div/>');\n",
  21260. " this._root_extra_style(this.root)\n",
  21261. " this.root.attr('style', 'display: inline-block');\n",
  21262. "\n",
  21263. " $(parent_element).append(this.root);\n",
  21264. "\n",
  21265. " this._init_header(this);\n",
  21266. " this._init_canvas(this);\n",
  21267. " this._init_toolbar(this);\n",
  21268. "\n",
  21269. " var fig = this;\n",
  21270. "\n",
  21271. " this.waiting = false;\n",
  21272. "\n",
  21273. " this.ws.onopen = function () {\n",
  21274. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  21275. " fig.send_message(\"send_image_mode\", {});\n",
  21276. " if (mpl.ratio != 1) {\n",
  21277. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  21278. " }\n",
  21279. " fig.send_message(\"refresh\", {});\n",
  21280. " }\n",
  21281. "\n",
  21282. " this.imageObj.onload = function() {\n",
  21283. " if (fig.image_mode == 'full') {\n",
  21284. " // Full images could contain transparency (where diff images\n",
  21285. " // almost always do), so we need to clear the canvas so that\n",
  21286. " // there is no ghosting.\n",
  21287. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  21288. " }\n",
  21289. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  21290. " };\n",
  21291. "\n",
  21292. " this.imageObj.onunload = function() {\n",
  21293. " fig.ws.close();\n",
  21294. " }\n",
  21295. "\n",
  21296. " this.ws.onmessage = this._make_on_message_function(this);\n",
  21297. "\n",
  21298. " this.ondownload = ondownload;\n",
  21299. "}\n",
  21300. "\n",
  21301. "mpl.figure.prototype._init_header = function() {\n",
  21302. " var titlebar = $(\n",
  21303. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  21304. " 'ui-helper-clearfix\"/>');\n",
  21305. " var titletext = $(\n",
  21306. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  21307. " 'text-align: center; padding: 3px;\"/>');\n",
  21308. " titlebar.append(titletext)\n",
  21309. " this.root.append(titlebar);\n",
  21310. " this.header = titletext[0];\n",
  21311. "}\n",
  21312. "\n",
  21313. "\n",
  21314. "\n",
  21315. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  21316. "\n",
  21317. "}\n",
  21318. "\n",
  21319. "\n",
  21320. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  21321. "\n",
  21322. "}\n",
  21323. "\n",
  21324. "mpl.figure.prototype._init_canvas = function() {\n",
  21325. " var fig = this;\n",
  21326. "\n",
  21327. " var canvas_div = $('<div/>');\n",
  21328. "\n",
  21329. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  21330. "\n",
  21331. " function canvas_keyboard_event(event) {\n",
  21332. " return fig.key_event(event, event['data']);\n",
  21333. " }\n",
  21334. "\n",
  21335. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  21336. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  21337. " this.canvas_div = canvas_div\n",
  21338. " this._canvas_extra_style(canvas_div)\n",
  21339. " this.root.append(canvas_div);\n",
  21340. "\n",
  21341. " var canvas = $('<canvas/>');\n",
  21342. " canvas.addClass('mpl-canvas');\n",
  21343. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  21344. "\n",
  21345. " this.canvas = canvas[0];\n",
  21346. " this.context = canvas[0].getContext(\"2d\");\n",
  21347. "\n",
  21348. " var backingStore = this.context.backingStorePixelRatio ||\n",
  21349. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  21350. "\tthis.context.mozBackingStorePixelRatio ||\n",
  21351. "\tthis.context.msBackingStorePixelRatio ||\n",
  21352. "\tthis.context.oBackingStorePixelRatio ||\n",
  21353. "\tthis.context.backingStorePixelRatio || 1;\n",
  21354. "\n",
  21355. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  21356. "\n",
  21357. " var rubberband = $('<canvas/>');\n",
  21358. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  21359. "\n",
  21360. " var pass_mouse_events = true;\n",
  21361. "\n",
  21362. " canvas_div.resizable({\n",
  21363. " start: function(event, ui) {\n",
  21364. " pass_mouse_events = false;\n",
  21365. " },\n",
  21366. " resize: function(event, ui) {\n",
  21367. " fig.request_resize(ui.size.width, ui.size.height);\n",
  21368. " },\n",
  21369. " stop: function(event, ui) {\n",
  21370. " pass_mouse_events = true;\n",
  21371. " fig.request_resize(ui.size.width, ui.size.height);\n",
  21372. " },\n",
  21373. " });\n",
  21374. "\n",
  21375. " function mouse_event_fn(event) {\n",
  21376. " if (pass_mouse_events)\n",
  21377. " return fig.mouse_event(event, event['data']);\n",
  21378. " }\n",
  21379. "\n",
  21380. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  21381. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  21382. " // Throttle sequential mouse events to 1 every 20ms.\n",
  21383. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  21384. "\n",
  21385. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  21386. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  21387. "\n",
  21388. " canvas_div.on(\"wheel\", function (event) {\n",
  21389. " event = event.originalEvent;\n",
  21390. " event['data'] = 'scroll'\n",
  21391. " if (event.deltaY < 0) {\n",
  21392. " event.step = 1;\n",
  21393. " } else {\n",
  21394. " event.step = -1;\n",
  21395. " }\n",
  21396. " mouse_event_fn(event);\n",
  21397. " });\n",
  21398. "\n",
  21399. " canvas_div.append(canvas);\n",
  21400. " canvas_div.append(rubberband);\n",
  21401. "\n",
  21402. " this.rubberband = rubberband;\n",
  21403. " this.rubberband_canvas = rubberband[0];\n",
  21404. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  21405. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  21406. "\n",
  21407. " this._resize_canvas = function(width, height) {\n",
  21408. " // Keep the size of the canvas, canvas container, and rubber band\n",
  21409. " // canvas in synch.\n",
  21410. " canvas_div.css('width', width)\n",
  21411. " canvas_div.css('height', height)\n",
  21412. "\n",
  21413. " canvas.attr('width', width * mpl.ratio);\n",
  21414. " canvas.attr('height', height * mpl.ratio);\n",
  21415. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  21416. "\n",
  21417. " rubberband.attr('width', width);\n",
  21418. " rubberband.attr('height', height);\n",
  21419. " }\n",
  21420. "\n",
  21421. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  21422. " // upon first draw.\n",
  21423. " this._resize_canvas(600, 600);\n",
  21424. "\n",
  21425. " // Disable right mouse context menu.\n",
  21426. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  21427. " return false;\n",
  21428. " });\n",
  21429. "\n",
  21430. " function set_focus () {\n",
  21431. " canvas.focus();\n",
  21432. " canvas_div.focus();\n",
  21433. " }\n",
  21434. "\n",
  21435. " window.setTimeout(set_focus, 100);\n",
  21436. "}\n",
  21437. "\n",
  21438. "mpl.figure.prototype._init_toolbar = function() {\n",
  21439. " var fig = this;\n",
  21440. "\n",
  21441. " var nav_element = $('<div/>')\n",
  21442. " nav_element.attr('style', 'width: 100%');\n",
  21443. " this.root.append(nav_element);\n",
  21444. "\n",
  21445. " // Define a callback function for later on.\n",
  21446. " function toolbar_event(event) {\n",
  21447. " return fig.toolbar_button_onclick(event['data']);\n",
  21448. " }\n",
  21449. " function toolbar_mouse_event(event) {\n",
  21450. " return fig.toolbar_button_onmouseover(event['data']);\n",
  21451. " }\n",
  21452. "\n",
  21453. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  21454. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  21455. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  21456. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  21457. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  21458. "\n",
  21459. " if (!name) {\n",
  21460. " // put a spacer in here.\n",
  21461. " continue;\n",
  21462. " }\n",
  21463. " var button = $('<button/>');\n",
  21464. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  21465. " 'ui-button-icon-only');\n",
  21466. " button.attr('role', 'button');\n",
  21467. " button.attr('aria-disabled', 'false');\n",
  21468. " button.click(method_name, toolbar_event);\n",
  21469. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  21470. "\n",
  21471. " var icon_img = $('<span/>');\n",
  21472. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  21473. " icon_img.addClass(image);\n",
  21474. " icon_img.addClass('ui-corner-all');\n",
  21475. "\n",
  21476. " var tooltip_span = $('<span/>');\n",
  21477. " tooltip_span.addClass('ui-button-text');\n",
  21478. " tooltip_span.html(tooltip);\n",
  21479. "\n",
  21480. " button.append(icon_img);\n",
  21481. " button.append(tooltip_span);\n",
  21482. "\n",
  21483. " nav_element.append(button);\n",
  21484. " }\n",
  21485. "\n",
  21486. " var fmt_picker_span = $('<span/>');\n",
  21487. "\n",
  21488. " var fmt_picker = $('<select/>');\n",
  21489. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  21490. " fmt_picker_span.append(fmt_picker);\n",
  21491. " nav_element.append(fmt_picker_span);\n",
  21492. " this.format_dropdown = fmt_picker[0];\n",
  21493. "\n",
  21494. " for (var ind in mpl.extensions) {\n",
  21495. " var fmt = mpl.extensions[ind];\n",
  21496. " var option = $(\n",
  21497. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  21498. " fmt_picker.append(option)\n",
  21499. " }\n",
  21500. "\n",
  21501. " // Add hover states to the ui-buttons\n",
  21502. " $( \".ui-button\" ).hover(\n",
  21503. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  21504. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  21505. " );\n",
  21506. "\n",
  21507. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  21508. " nav_element.append(status_bar);\n",
  21509. " this.message = status_bar[0];\n",
  21510. "}\n",
  21511. "\n",
  21512. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  21513. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  21514. " // which will in turn request a refresh of the image.\n",
  21515. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  21516. "}\n",
  21517. "\n",
  21518. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  21519. " properties['type'] = type;\n",
  21520. " properties['figure_id'] = this.id;\n",
  21521. " this.ws.send(JSON.stringify(properties));\n",
  21522. "}\n",
  21523. "\n",
  21524. "mpl.figure.prototype.send_draw_message = function() {\n",
  21525. " if (!this.waiting) {\n",
  21526. " this.waiting = true;\n",
  21527. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  21528. " }\n",
  21529. "}\n",
  21530. "\n",
  21531. "\n",
  21532. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  21533. " var format_dropdown = fig.format_dropdown;\n",
  21534. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  21535. " fig.ondownload(fig, format);\n",
  21536. "}\n",
  21537. "\n",
  21538. "\n",
  21539. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  21540. " var size = msg['size'];\n",
  21541. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  21542. " fig._resize_canvas(size[0], size[1]);\n",
  21543. " fig.send_message(\"refresh\", {});\n",
  21544. " };\n",
  21545. "}\n",
  21546. "\n",
  21547. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  21548. " var x0 = msg['x0'] / mpl.ratio;\n",
  21549. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  21550. " var x1 = msg['x1'] / mpl.ratio;\n",
  21551. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  21552. " x0 = Math.floor(x0) + 0.5;\n",
  21553. " y0 = Math.floor(y0) + 0.5;\n",
  21554. " x1 = Math.floor(x1) + 0.5;\n",
  21555. " y1 = Math.floor(y1) + 0.5;\n",
  21556. " var min_x = Math.min(x0, x1);\n",
  21557. " var min_y = Math.min(y0, y1);\n",
  21558. " var width = Math.abs(x1 - x0);\n",
  21559. " var height = Math.abs(y1 - y0);\n",
  21560. "\n",
  21561. " fig.rubberband_context.clearRect(\n",
  21562. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  21563. "\n",
  21564. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  21565. "}\n",
  21566. "\n",
  21567. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  21568. " // Updates the figure title.\n",
  21569. " fig.header.textContent = msg['label'];\n",
  21570. "}\n",
  21571. "\n",
  21572. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  21573. " var cursor = msg['cursor'];\n",
  21574. " switch(cursor)\n",
  21575. " {\n",
  21576. " case 0:\n",
  21577. " cursor = 'pointer';\n",
  21578. " break;\n",
  21579. " case 1:\n",
  21580. " cursor = 'default';\n",
  21581. " break;\n",
  21582. " case 2:\n",
  21583. " cursor = 'crosshair';\n",
  21584. " break;\n",
  21585. " case 3:\n",
  21586. " cursor = 'move';\n",
  21587. " break;\n",
  21588. " }\n",
  21589. " fig.rubberband_canvas.style.cursor = cursor;\n",
  21590. "}\n",
  21591. "\n",
  21592. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  21593. " fig.message.textContent = msg['message'];\n",
  21594. "}\n",
  21595. "\n",
  21596. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  21597. " // Request the server to send over a new figure.\n",
  21598. " fig.send_draw_message();\n",
  21599. "}\n",
  21600. "\n",
  21601. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  21602. " fig.image_mode = msg['mode'];\n",
  21603. "}\n",
  21604. "\n",
  21605. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  21606. " // Called whenever the canvas gets updated.\n",
  21607. " this.send_message(\"ack\", {});\n",
  21608. "}\n",
  21609. "\n",
  21610. "// A function to construct a web socket function for onmessage handling.\n",
  21611. "// Called in the figure constructor.\n",
  21612. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  21613. " return function socket_on_message(evt) {\n",
  21614. " if (evt.data instanceof Blob) {\n",
  21615. " /* FIXME: We get \"Resource interpreted as Image but\n",
  21616. " * transferred with MIME type text/plain:\" errors on\n",
  21617. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  21618. " * to be part of the websocket stream */\n",
  21619. " evt.data.type = \"image/png\";\n",
  21620. "\n",
  21621. " /* Free the memory for the previous frames */\n",
  21622. " if (fig.imageObj.src) {\n",
  21623. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  21624. " fig.imageObj.src);\n",
  21625. " }\n",
  21626. "\n",
  21627. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  21628. " evt.data);\n",
  21629. " fig.updated_canvas_event();\n",
  21630. " fig.waiting = false;\n",
  21631. " return;\n",
  21632. " }\n",
  21633. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  21634. " fig.imageObj.src = evt.data;\n",
  21635. " fig.updated_canvas_event();\n",
  21636. " fig.waiting = false;\n",
  21637. " return;\n",
  21638. " }\n",
  21639. "\n",
  21640. " var msg = JSON.parse(evt.data);\n",
  21641. " var msg_type = msg['type'];\n",
  21642. "\n",
  21643. " // Call the \"handle_{type}\" callback, which takes\n",
  21644. " // the figure and JSON message as its only arguments.\n",
  21645. " try {\n",
  21646. " var callback = fig[\"handle_\" + msg_type];\n",
  21647. " } catch (e) {\n",
  21648. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  21649. " return;\n",
  21650. " }\n",
  21651. "\n",
  21652. " if (callback) {\n",
  21653. " try {\n",
  21654. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  21655. " callback(fig, msg);\n",
  21656. " } catch (e) {\n",
  21657. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  21658. " }\n",
  21659. " }\n",
  21660. " };\n",
  21661. "}\n",
  21662. "\n",
  21663. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  21664. "mpl.findpos = function(e) {\n",
  21665. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  21666. " var targ;\n",
  21667. " if (!e)\n",
  21668. " e = window.event;\n",
  21669. " if (e.target)\n",
  21670. " targ = e.target;\n",
  21671. " else if (e.srcElement)\n",
  21672. " targ = e.srcElement;\n",
  21673. " if (targ.nodeType == 3) // defeat Safari bug\n",
  21674. " targ = targ.parentNode;\n",
  21675. "\n",
  21676. " // jQuery normalizes the pageX and pageY\n",
  21677. " // pageX,Y are the mouse positions relative to the document\n",
  21678. " // offset() returns the position of the element relative to the document\n",
  21679. " var x = e.pageX - $(targ).offset().left;\n",
  21680. " var y = e.pageY - $(targ).offset().top;\n",
  21681. "\n",
  21682. " return {\"x\": x, \"y\": y};\n",
  21683. "};\n",
  21684. "\n",
  21685. "/*\n",
  21686. " * return a copy of an object with only non-object keys\n",
  21687. " * we need this to avoid circular references\n",
  21688. " * http://stackoverflow.com/a/24161582/3208463\n",
  21689. " */\n",
  21690. "function simpleKeys (original) {\n",
  21691. " return Object.keys(original).reduce(function (obj, key) {\n",
  21692. " if (typeof original[key] !== 'object')\n",
  21693. " obj[key] = original[key]\n",
  21694. " return obj;\n",
  21695. " }, {});\n",
  21696. "}\n",
  21697. "\n",
  21698. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  21699. " var canvas_pos = mpl.findpos(event)\n",
  21700. "\n",
  21701. " if (name === 'button_press')\n",
  21702. " {\n",
  21703. " this.canvas.focus();\n",
  21704. " this.canvas_div.focus();\n",
  21705. " }\n",
  21706. "\n",
  21707. " var x = canvas_pos.x * mpl.ratio;\n",
  21708. " var y = canvas_pos.y * mpl.ratio;\n",
  21709. "\n",
  21710. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  21711. " step: event.step,\n",
  21712. " guiEvent: simpleKeys(event)});\n",
  21713. "\n",
  21714. " /* This prevents the web browser from automatically changing to\n",
  21715. " * the text insertion cursor when the button is pressed. We want\n",
  21716. " * to control all of the cursor setting manually through the\n",
  21717. " * 'cursor' event from matplotlib */\n",
  21718. " event.preventDefault();\n",
  21719. " return false;\n",
  21720. "}\n",
  21721. "\n",
  21722. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  21723. " // Handle any extra behaviour associated with a key event\n",
  21724. "}\n",
  21725. "\n",
  21726. "mpl.figure.prototype.key_event = function(event, name) {\n",
  21727. "\n",
  21728. " // Prevent repeat events\n",
  21729. " if (name == 'key_press')\n",
  21730. " {\n",
  21731. " if (event.which === this._key)\n",
  21732. " return;\n",
  21733. " else\n",
  21734. " this._key = event.which;\n",
  21735. " }\n",
  21736. " if (name == 'key_release')\n",
  21737. " this._key = null;\n",
  21738. "\n",
  21739. " var value = '';\n",
  21740. " if (event.ctrlKey && event.which != 17)\n",
  21741. " value += \"ctrl+\";\n",
  21742. " if (event.altKey && event.which != 18)\n",
  21743. " value += \"alt+\";\n",
  21744. " if (event.shiftKey && event.which != 16)\n",
  21745. " value += \"shift+\";\n",
  21746. "\n",
  21747. " value += 'k';\n",
  21748. " value += event.which.toString();\n",
  21749. "\n",
  21750. " this._key_event_extra(event, name);\n",
  21751. "\n",
  21752. " this.send_message(name, {key: value,\n",
  21753. " guiEvent: simpleKeys(event)});\n",
  21754. " return false;\n",
  21755. "}\n",
  21756. "\n",
  21757. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  21758. " if (name == 'download') {\n",
  21759. " this.handle_save(this, null);\n",
  21760. " } else {\n",
  21761. " this.send_message(\"toolbar_button\", {name: name});\n",
  21762. " }\n",
  21763. "};\n",
  21764. "\n",
  21765. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  21766. " this.message.textContent = tooltip;\n",
  21767. "};\n",
  21768. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  21769. "\n",
  21770. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  21771. "\n",
  21772. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  21773. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  21774. " // object with the appropriate methods. Currently this is a non binary\n",
  21775. " // socket, so there is still some room for performance tuning.\n",
  21776. " var ws = {};\n",
  21777. "\n",
  21778. " ws.close = function() {\n",
  21779. " comm.close()\n",
  21780. " };\n",
  21781. " ws.send = function(m) {\n",
  21782. " //console.log('sending', m);\n",
  21783. " comm.send(m);\n",
  21784. " };\n",
  21785. " // Register the callback with on_msg.\n",
  21786. " comm.on_msg(function(msg) {\n",
  21787. " //console.log('receiving', msg['content']['data'], msg);\n",
  21788. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  21789. " ws.onmessage(msg['content']['data'])\n",
  21790. " });\n",
  21791. " return ws;\n",
  21792. "}\n",
  21793. "\n",
  21794. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  21795. " // This is the function which gets called when the mpl process\n",
  21796. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  21797. "\n",
  21798. " var id = msg.content.data.id;\n",
  21799. " // Get hold of the div created by the display call when the Comm\n",
  21800. " // socket was opened in Python.\n",
  21801. " var element = $(\"#\" + id);\n",
  21802. " var ws_proxy = comm_websocket_adapter(comm)\n",
  21803. "\n",
  21804. " function ondownload(figure, format) {\n",
  21805. " window.open(figure.imageObj.src);\n",
  21806. " }\n",
  21807. "\n",
  21808. " var fig = new mpl.figure(id, ws_proxy,\n",
  21809. " ondownload,\n",
  21810. " element.get(0));\n",
  21811. "\n",
  21812. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  21813. " // web socket which is closed, not our websocket->open comm proxy.\n",
  21814. " ws_proxy.onopen();\n",
  21815. "\n",
  21816. " fig.parent_element = element.get(0);\n",
  21817. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  21818. " if (!fig.cell_info) {\n",
  21819. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  21820. " return;\n",
  21821. " }\n",
  21822. "\n",
  21823. " var output_index = fig.cell_info[2]\n",
  21824. " var cell = fig.cell_info[0];\n",
  21825. "\n",
  21826. "};\n",
  21827. "\n",
  21828. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  21829. " var width = fig.canvas.width/mpl.ratio\n",
  21830. " fig.root.unbind('remove')\n",
  21831. "\n",
  21832. " // Update the output cell to use the data from the current canvas.\n",
  21833. " fig.push_to_output();\n",
  21834. " var dataURL = fig.canvas.toDataURL();\n",
  21835. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  21836. " // the notebook keyboard shortcuts fail.\n",
  21837. " IPython.keyboard_manager.enable()\n",
  21838. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  21839. " fig.close_ws(fig, msg);\n",
  21840. "}\n",
  21841. "\n",
  21842. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  21843. " fig.send_message('closing', msg);\n",
  21844. " // fig.ws.close()\n",
  21845. "}\n",
  21846. "\n",
  21847. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  21848. " // Turn the data on the canvas into data in the output cell.\n",
  21849. " var width = this.canvas.width/mpl.ratio\n",
  21850. " var dataURL = this.canvas.toDataURL();\n",
  21851. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  21852. "}\n",
  21853. "\n",
  21854. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  21855. " // Tell IPython that the notebook contents must change.\n",
  21856. " IPython.notebook.set_dirty(true);\n",
  21857. " this.send_message(\"ack\", {});\n",
  21858. " var fig = this;\n",
  21859. " // Wait a second, then push the new image to the DOM so\n",
  21860. " // that it is saved nicely (might be nice to debounce this).\n",
  21861. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  21862. "}\n",
  21863. "\n",
  21864. "mpl.figure.prototype._init_toolbar = function() {\n",
  21865. " var fig = this;\n",
  21866. "\n",
  21867. " var nav_element = $('<div/>')\n",
  21868. " nav_element.attr('style', 'width: 100%');\n",
  21869. " this.root.append(nav_element);\n",
  21870. "\n",
  21871. " // Define a callback function for later on.\n",
  21872. " function toolbar_event(event) {\n",
  21873. " return fig.toolbar_button_onclick(event['data']);\n",
  21874. " }\n",
  21875. " function toolbar_mouse_event(event) {\n",
  21876. " return fig.toolbar_button_onmouseover(event['data']);\n",
  21877. " }\n",
  21878. "\n",
  21879. " for(var toolbar_ind in mpl.toolbar_items){\n",
  21880. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  21881. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  21882. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  21883. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  21884. "\n",
  21885. " if (!name) { continue; };\n",
  21886. "\n",
  21887. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  21888. " button.click(method_name, toolbar_event);\n",
  21889. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  21890. " nav_element.append(button);\n",
  21891. " }\n",
  21892. "\n",
  21893. " // Add the status bar.\n",
  21894. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  21895. " nav_element.append(status_bar);\n",
  21896. " this.message = status_bar[0];\n",
  21897. "\n",
  21898. " // Add the close button to the window.\n",
  21899. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  21900. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  21901. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  21902. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  21903. " buttongrp.append(button);\n",
  21904. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  21905. " titlebar.prepend(buttongrp);\n",
  21906. "}\n",
  21907. "\n",
  21908. "mpl.figure.prototype._root_extra_style = function(el){\n",
  21909. " var fig = this\n",
  21910. " el.on(\"remove\", function(){\n",
  21911. "\tfig.close_ws(fig, {});\n",
  21912. " });\n",
  21913. "}\n",
  21914. "\n",
  21915. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  21916. " // this is important to make the div 'focusable\n",
  21917. " el.attr('tabindex', 0)\n",
  21918. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  21919. " // off when our div gets focus\n",
  21920. "\n",
  21921. " // location in version 3\n",
  21922. " if (IPython.notebook.keyboard_manager) {\n",
  21923. " IPython.notebook.keyboard_manager.register_events(el);\n",
  21924. " }\n",
  21925. " else {\n",
  21926. " // location in version 2\n",
  21927. " IPython.keyboard_manager.register_events(el);\n",
  21928. " }\n",
  21929. "\n",
  21930. "}\n",
  21931. "\n",
  21932. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  21933. " var manager = IPython.notebook.keyboard_manager;\n",
  21934. " if (!manager)\n",
  21935. " manager = IPython.keyboard_manager;\n",
  21936. "\n",
  21937. " // Check for shift+enter\n",
  21938. " if (event.shiftKey && event.which == 13) {\n",
  21939. " this.canvas_div.blur();\n",
  21940. " event.shiftKey = false;\n",
  21941. " // Send a \"J\" for go to next cell\n",
  21942. " event.which = 74;\n",
  21943. " event.keyCode = 74;\n",
  21944. " manager.command_mode();\n",
  21945. " manager.handle_keydown(event);\n",
  21946. " }\n",
  21947. "}\n",
  21948. "\n",
  21949. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  21950. " fig.ondownload(fig, null);\n",
  21951. "}\n",
  21952. "\n",
  21953. "\n",
  21954. "mpl.find_output_cell = function(html_output) {\n",
  21955. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  21956. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  21957. " // IPython event is triggered only after the cells have been serialised, which for\n",
  21958. " // our purposes (turning an active figure into a static one), is too late.\n",
  21959. " var cells = IPython.notebook.get_cells();\n",
  21960. " var ncells = cells.length;\n",
  21961. " for (var i=0; i<ncells; i++) {\n",
  21962. " var cell = cells[i];\n",
  21963. " if (cell.cell_type === 'code'){\n",
  21964. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  21965. " var data = cell.output_area.outputs[j];\n",
  21966. " if (data.data) {\n",
  21967. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  21968. " data = data.data;\n",
  21969. " }\n",
  21970. " if (data['text/html'] == html_output) {\n",
  21971. " return [cell, data, j];\n",
  21972. " }\n",
  21973. " }\n",
  21974. " }\n",
  21975. " }\n",
  21976. "}\n",
  21977. "\n",
  21978. "// Register the function which deals with the matplotlib target/channel.\n",
  21979. "// The kernel may be null if the page has been refreshed.\n",
  21980. "if (IPython.notebook.kernel != null) {\n",
  21981. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  21982. "}\n"
  21983. ],
  21984. "text/plain": [
  21985. "<IPython.core.display.Javascript object>"
  21986. ]
  21987. },
  21988. "metadata": {},
  21989. "output_type": "display_data"
  21990. },
  21991. {
  21992. "data": {
  21993. "text/html": [
  21994. "<img src=\"data:image/png;base64,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TIH1R2MVsBMJVTFvi2LtUGkVbOFwEMTOW7hyVbG6U8GWwaOxoOXNJBvn3iCEsb0QZ4gEMACAucV1IvIHIvIXIvL+4NqQJAewbwfXf77Mc303uP1ngq8/EHz9dpn7VwS3/+NlvM4/LOM7BDDE9OgHsXhFzN+eGFbD3DbG00EnwmPjQ1bJtsE9USUrbjx8NRwkeOHMkAAGADC3OCsi/y6lVa0hSQ5gPwyuX1fmub4lpdWum4Ovv1nm/j8R3P6Dy3idBDDEWWbJeTC/QcdAFL7i58hc90RX3XLhKymA+VUvF7qm+z0jJkkAAwCYO6wVkR+JyFjs+pDMvABWDrYgIiJiqiWAAQDMDa4T23b4NRH5qdhtQzLztiCWgwCGiIiplgAGADA3+FmJBi5fyueDx9CEAxERcYolgAEAzA3eLyKvlvGPJApGr4rI1uAxtKFHREScYglgAAAwJMlbEKuEQcyIiIhTKgEMAACGJDmAiYjsDm57Q0ReFpsd9npwLV/m+QoSbU+8GDzujeDarqt8rQQwRERMtQQwAAAYkvIBTETkDhH5klhzjXdE5Csisu0Sz/l4cL93gsd9SUQ2X/1LJYAhImK6JYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAECaIIAhImKqJYABAMwdXhMRLeM/lHlMq4h8QUT+WUS+JyJ/KiL7ROR9E/w9m0XkiyLyloh8V0R+T0S2Xe2LDyCAISJiqiWAAQDMHV4Tke+IyFCChxLu/wsi8iOxEPUpEcmJyNfFAtvnyvwdu4Lb3xCRl0Xkooi8HlzLX/U7IIAhImLKJYABAMwdXgu8HD4kIv8kIj8QkWbv+k+LyO+KBaoHYo+pFJHvi8ibwZ8d14vIN4LHtEzqFY+HAIaIiKmWAAYAMHd4TS4/gD0pFph+OeG2ruC2L8Wunw2un5nk800GAhgiIqZaAhgAwNzhNRH5exF5REROiMheEdkoyee5PisWmB5MuO06EXlHRP5NRH7Ku/5lKV/luim47fUre+khBDBEREy1BDAAgLnDa5LcgONvRGRD7L5fCW5bVea5/iy4fYl37dvBtZ8v85jvBrf/zGW81j8s4zsEMERETLMEMACAucOg2PbBj4qFoEYR+biI/FhE/lVElnv3/UuxsLSwzHP9joyvdv0wuHZdmcd8K7j9pst4rQQwRESclRLAAAAgLxaMfs27Nt0BrBxsQURExFRLAAMAgIViwehN79p0b0EsBwEMERFTLQEMAAA+LBaMvu9dowkHIiLiuyABDAAAMmLh6GveNdrQIyIivgsSwAAA5gZLROQDCdcr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\" width=\"432\">"
  21995. ],
  21996. "text/plain": [
  21997. "<IPython.core.display.HTML object>"
  21998. ]
  21999. },
  22000. "metadata": {},
  22001. "output_type": "display_data"
  22002. },
  22003. {
  22004. "name": "stdout",
  22005. "output_type": "stream",
  22006. "text": [
  22007. "0.0 1.0\n",
  22008. "665.0\n",
  22009. "(350, 316)\n",
  22010. "\n"
  22011. ]
  22012. },
  22013. {
  22014. "data": {
  22015. "application/javascript": [
  22016. "/* Put everything inside the global mpl namespace */\n",
  22017. "window.mpl = {};\n",
  22018. "\n",
  22019. "\n",
  22020. "mpl.get_websocket_type = function() {\n",
  22021. " if (typeof(WebSocket) !== 'undefined') {\n",
  22022. " return WebSocket;\n",
  22023. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  22024. " return MozWebSocket;\n",
  22025. " } else {\n",
  22026. " alert('Your browser does not have WebSocket support.' +\n",
  22027. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  22028. " 'Firefox 4 and 5 are also supported but you ' +\n",
  22029. " 'have to enable WebSockets in about:config.');\n",
  22030. " };\n",
  22031. "}\n",
  22032. "\n",
  22033. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  22034. " this.id = figure_id;\n",
  22035. "\n",
  22036. " this.ws = websocket;\n",
  22037. "\n",
  22038. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  22039. "\n",
  22040. " if (!this.supports_binary) {\n",
  22041. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  22042. " if (warnings) {\n",
  22043. " warnings.style.display = 'block';\n",
  22044. " warnings.textContent = (\n",
  22045. " \"This browser does not support binary websocket messages. \" +\n",
  22046. " \"Performance may be slow.\");\n",
  22047. " }\n",
  22048. " }\n",
  22049. "\n",
  22050. " this.imageObj = new Image();\n",
  22051. "\n",
  22052. " this.context = undefined;\n",
  22053. " this.message = undefined;\n",
  22054. " this.canvas = undefined;\n",
  22055. " this.rubberband_canvas = undefined;\n",
  22056. " this.rubberband_context = undefined;\n",
  22057. " this.format_dropdown = undefined;\n",
  22058. "\n",
  22059. " this.image_mode = 'full';\n",
  22060. "\n",
  22061. " this.root = $('<div/>');\n",
  22062. " this._root_extra_style(this.root)\n",
  22063. " this.root.attr('style', 'display: inline-block');\n",
  22064. "\n",
  22065. " $(parent_element).append(this.root);\n",
  22066. "\n",
  22067. " this._init_header(this);\n",
  22068. " this._init_canvas(this);\n",
  22069. " this._init_toolbar(this);\n",
  22070. "\n",
  22071. " var fig = this;\n",
  22072. "\n",
  22073. " this.waiting = false;\n",
  22074. "\n",
  22075. " this.ws.onopen = function () {\n",
  22076. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  22077. " fig.send_message(\"send_image_mode\", {});\n",
  22078. " if (mpl.ratio != 1) {\n",
  22079. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  22080. " }\n",
  22081. " fig.send_message(\"refresh\", {});\n",
  22082. " }\n",
  22083. "\n",
  22084. " this.imageObj.onload = function() {\n",
  22085. " if (fig.image_mode == 'full') {\n",
  22086. " // Full images could contain transparency (where diff images\n",
  22087. " // almost always do), so we need to clear the canvas so that\n",
  22088. " // there is no ghosting.\n",
  22089. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  22090. " }\n",
  22091. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  22092. " };\n",
  22093. "\n",
  22094. " this.imageObj.onunload = function() {\n",
  22095. " fig.ws.close();\n",
  22096. " }\n",
  22097. "\n",
  22098. " this.ws.onmessage = this._make_on_message_function(this);\n",
  22099. "\n",
  22100. " this.ondownload = ondownload;\n",
  22101. "}\n",
  22102. "\n",
  22103. "mpl.figure.prototype._init_header = function() {\n",
  22104. " var titlebar = $(\n",
  22105. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  22106. " 'ui-helper-clearfix\"/>');\n",
  22107. " var titletext = $(\n",
  22108. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  22109. " 'text-align: center; padding: 3px;\"/>');\n",
  22110. " titlebar.append(titletext)\n",
  22111. " this.root.append(titlebar);\n",
  22112. " this.header = titletext[0];\n",
  22113. "}\n",
  22114. "\n",
  22115. "\n",
  22116. "\n",
  22117. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  22118. "\n",
  22119. "}\n",
  22120. "\n",
  22121. "\n",
  22122. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  22123. "\n",
  22124. "}\n",
  22125. "\n",
  22126. "mpl.figure.prototype._init_canvas = function() {\n",
  22127. " var fig = this;\n",
  22128. "\n",
  22129. " var canvas_div = $('<div/>');\n",
  22130. "\n",
  22131. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  22132. "\n",
  22133. " function canvas_keyboard_event(event) {\n",
  22134. " return fig.key_event(event, event['data']);\n",
  22135. " }\n",
  22136. "\n",
  22137. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  22138. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  22139. " this.canvas_div = canvas_div\n",
  22140. " this._canvas_extra_style(canvas_div)\n",
  22141. " this.root.append(canvas_div);\n",
  22142. "\n",
  22143. " var canvas = $('<canvas/>');\n",
  22144. " canvas.addClass('mpl-canvas');\n",
  22145. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  22146. "\n",
  22147. " this.canvas = canvas[0];\n",
  22148. " this.context = canvas[0].getContext(\"2d\");\n",
  22149. "\n",
  22150. " var backingStore = this.context.backingStorePixelRatio ||\n",
  22151. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  22152. "\tthis.context.mozBackingStorePixelRatio ||\n",
  22153. "\tthis.context.msBackingStorePixelRatio ||\n",
  22154. "\tthis.context.oBackingStorePixelRatio ||\n",
  22155. "\tthis.context.backingStorePixelRatio || 1;\n",
  22156. "\n",
  22157. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  22158. "\n",
  22159. " var rubberband = $('<canvas/>');\n",
  22160. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  22161. "\n",
  22162. " var pass_mouse_events = true;\n",
  22163. "\n",
  22164. " canvas_div.resizable({\n",
  22165. " start: function(event, ui) {\n",
  22166. " pass_mouse_events = false;\n",
  22167. " },\n",
  22168. " resize: function(event, ui) {\n",
  22169. " fig.request_resize(ui.size.width, ui.size.height);\n",
  22170. " },\n",
  22171. " stop: function(event, ui) {\n",
  22172. " pass_mouse_events = true;\n",
  22173. " fig.request_resize(ui.size.width, ui.size.height);\n",
  22174. " },\n",
  22175. " });\n",
  22176. "\n",
  22177. " function mouse_event_fn(event) {\n",
  22178. " if (pass_mouse_events)\n",
  22179. " return fig.mouse_event(event, event['data']);\n",
  22180. " }\n",
  22181. "\n",
  22182. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  22183. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  22184. " // Throttle sequential mouse events to 1 every 20ms.\n",
  22185. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  22186. "\n",
  22187. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  22188. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  22189. "\n",
  22190. " canvas_div.on(\"wheel\", function (event) {\n",
  22191. " event = event.originalEvent;\n",
  22192. " event['data'] = 'scroll'\n",
  22193. " if (event.deltaY < 0) {\n",
  22194. " event.step = 1;\n",
  22195. " } else {\n",
  22196. " event.step = -1;\n",
  22197. " }\n",
  22198. " mouse_event_fn(event);\n",
  22199. " });\n",
  22200. "\n",
  22201. " canvas_div.append(canvas);\n",
  22202. " canvas_div.append(rubberband);\n",
  22203. "\n",
  22204. " this.rubberband = rubberband;\n",
  22205. " this.rubberband_canvas = rubberband[0];\n",
  22206. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  22207. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  22208. "\n",
  22209. " this._resize_canvas = function(width, height) {\n",
  22210. " // Keep the size of the canvas, canvas container, and rubber band\n",
  22211. " // canvas in synch.\n",
  22212. " canvas_div.css('width', width)\n",
  22213. " canvas_div.css('height', height)\n",
  22214. "\n",
  22215. " canvas.attr('width', width * mpl.ratio);\n",
  22216. " canvas.attr('height', height * mpl.ratio);\n",
  22217. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  22218. "\n",
  22219. " rubberband.attr('width', width);\n",
  22220. " rubberband.attr('height', height);\n",
  22221. " }\n",
  22222. "\n",
  22223. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  22224. " // upon first draw.\n",
  22225. " this._resize_canvas(600, 600);\n",
  22226. "\n",
  22227. " // Disable right mouse context menu.\n",
  22228. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  22229. " return false;\n",
  22230. " });\n",
  22231. "\n",
  22232. " function set_focus () {\n",
  22233. " canvas.focus();\n",
  22234. " canvas_div.focus();\n",
  22235. " }\n",
  22236. "\n",
  22237. " window.setTimeout(set_focus, 100);\n",
  22238. "}\n",
  22239. "\n",
  22240. "mpl.figure.prototype._init_toolbar = function() {\n",
  22241. " var fig = this;\n",
  22242. "\n",
  22243. " var nav_element = $('<div/>')\n",
  22244. " nav_element.attr('style', 'width: 100%');\n",
  22245. " this.root.append(nav_element);\n",
  22246. "\n",
  22247. " // Define a callback function for later on.\n",
  22248. " function toolbar_event(event) {\n",
  22249. " return fig.toolbar_button_onclick(event['data']);\n",
  22250. " }\n",
  22251. " function toolbar_mouse_event(event) {\n",
  22252. " return fig.toolbar_button_onmouseover(event['data']);\n",
  22253. " }\n",
  22254. "\n",
  22255. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  22256. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  22257. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  22258. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  22259. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  22260. "\n",
  22261. " if (!name) {\n",
  22262. " // put a spacer in here.\n",
  22263. " continue;\n",
  22264. " }\n",
  22265. " var button = $('<button/>');\n",
  22266. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  22267. " 'ui-button-icon-only');\n",
  22268. " button.attr('role', 'button');\n",
  22269. " button.attr('aria-disabled', 'false');\n",
  22270. " button.click(method_name, toolbar_event);\n",
  22271. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  22272. "\n",
  22273. " var icon_img = $('<span/>');\n",
  22274. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  22275. " icon_img.addClass(image);\n",
  22276. " icon_img.addClass('ui-corner-all');\n",
  22277. "\n",
  22278. " var tooltip_span = $('<span/>');\n",
  22279. " tooltip_span.addClass('ui-button-text');\n",
  22280. " tooltip_span.html(tooltip);\n",
  22281. "\n",
  22282. " button.append(icon_img);\n",
  22283. " button.append(tooltip_span);\n",
  22284. "\n",
  22285. " nav_element.append(button);\n",
  22286. " }\n",
  22287. "\n",
  22288. " var fmt_picker_span = $('<span/>');\n",
  22289. "\n",
  22290. " var fmt_picker = $('<select/>');\n",
  22291. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  22292. " fmt_picker_span.append(fmt_picker);\n",
  22293. " nav_element.append(fmt_picker_span);\n",
  22294. " this.format_dropdown = fmt_picker[0];\n",
  22295. "\n",
  22296. " for (var ind in mpl.extensions) {\n",
  22297. " var fmt = mpl.extensions[ind];\n",
  22298. " var option = $(\n",
  22299. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  22300. " fmt_picker.append(option)\n",
  22301. " }\n",
  22302. "\n",
  22303. " // Add hover states to the ui-buttons\n",
  22304. " $( \".ui-button\" ).hover(\n",
  22305. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  22306. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  22307. " );\n",
  22308. "\n",
  22309. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  22310. " nav_element.append(status_bar);\n",
  22311. " this.message = status_bar[0];\n",
  22312. "}\n",
  22313. "\n",
  22314. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  22315. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  22316. " // which will in turn request a refresh of the image.\n",
  22317. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  22318. "}\n",
  22319. "\n",
  22320. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  22321. " properties['type'] = type;\n",
  22322. " properties['figure_id'] = this.id;\n",
  22323. " this.ws.send(JSON.stringify(properties));\n",
  22324. "}\n",
  22325. "\n",
  22326. "mpl.figure.prototype.send_draw_message = function() {\n",
  22327. " if (!this.waiting) {\n",
  22328. " this.waiting = true;\n",
  22329. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  22330. " }\n",
  22331. "}\n",
  22332. "\n",
  22333. "\n",
  22334. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  22335. " var format_dropdown = fig.format_dropdown;\n",
  22336. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  22337. " fig.ondownload(fig, format);\n",
  22338. "}\n",
  22339. "\n",
  22340. "\n",
  22341. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  22342. " var size = msg['size'];\n",
  22343. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  22344. " fig._resize_canvas(size[0], size[1]);\n",
  22345. " fig.send_message(\"refresh\", {});\n",
  22346. " };\n",
  22347. "}\n",
  22348. "\n",
  22349. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  22350. " var x0 = msg['x0'] / mpl.ratio;\n",
  22351. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  22352. " var x1 = msg['x1'] / mpl.ratio;\n",
  22353. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  22354. " x0 = Math.floor(x0) + 0.5;\n",
  22355. " y0 = Math.floor(y0) + 0.5;\n",
  22356. " x1 = Math.floor(x1) + 0.5;\n",
  22357. " y1 = Math.floor(y1) + 0.5;\n",
  22358. " var min_x = Math.min(x0, x1);\n",
  22359. " var min_y = Math.min(y0, y1);\n",
  22360. " var width = Math.abs(x1 - x0);\n",
  22361. " var height = Math.abs(y1 - y0);\n",
  22362. "\n",
  22363. " fig.rubberband_context.clearRect(\n",
  22364. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  22365. "\n",
  22366. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  22367. "}\n",
  22368. "\n",
  22369. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  22370. " // Updates the figure title.\n",
  22371. " fig.header.textContent = msg['label'];\n",
  22372. "}\n",
  22373. "\n",
  22374. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  22375. " var cursor = msg['cursor'];\n",
  22376. " switch(cursor)\n",
  22377. " {\n",
  22378. " case 0:\n",
  22379. " cursor = 'pointer';\n",
  22380. " break;\n",
  22381. " case 1:\n",
  22382. " cursor = 'default';\n",
  22383. " break;\n",
  22384. " case 2:\n",
  22385. " cursor = 'crosshair';\n",
  22386. " break;\n",
  22387. " case 3:\n",
  22388. " cursor = 'move';\n",
  22389. " break;\n",
  22390. " }\n",
  22391. " fig.rubberband_canvas.style.cursor = cursor;\n",
  22392. "}\n",
  22393. "\n",
  22394. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  22395. " fig.message.textContent = msg['message'];\n",
  22396. "}\n",
  22397. "\n",
  22398. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  22399. " // Request the server to send over a new figure.\n",
  22400. " fig.send_draw_message();\n",
  22401. "}\n",
  22402. "\n",
  22403. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  22404. " fig.image_mode = msg['mode'];\n",
  22405. "}\n",
  22406. "\n",
  22407. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  22408. " // Called whenever the canvas gets updated.\n",
  22409. " this.send_message(\"ack\", {});\n",
  22410. "}\n",
  22411. "\n",
  22412. "// A function to construct a web socket function for onmessage handling.\n",
  22413. "// Called in the figure constructor.\n",
  22414. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  22415. " return function socket_on_message(evt) {\n",
  22416. " if (evt.data instanceof Blob) {\n",
  22417. " /* FIXME: We get \"Resource interpreted as Image but\n",
  22418. " * transferred with MIME type text/plain:\" errors on\n",
  22419. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  22420. " * to be part of the websocket stream */\n",
  22421. " evt.data.type = \"image/png\";\n",
  22422. "\n",
  22423. " /* Free the memory for the previous frames */\n",
  22424. " if (fig.imageObj.src) {\n",
  22425. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  22426. " fig.imageObj.src);\n",
  22427. " }\n",
  22428. "\n",
  22429. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  22430. " evt.data);\n",
  22431. " fig.updated_canvas_event();\n",
  22432. " fig.waiting = false;\n",
  22433. " return;\n",
  22434. " }\n",
  22435. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  22436. " fig.imageObj.src = evt.data;\n",
  22437. " fig.updated_canvas_event();\n",
  22438. " fig.waiting = false;\n",
  22439. " return;\n",
  22440. " }\n",
  22441. "\n",
  22442. " var msg = JSON.parse(evt.data);\n",
  22443. " var msg_type = msg['type'];\n",
  22444. "\n",
  22445. " // Call the \"handle_{type}\" callback, which takes\n",
  22446. " // the figure and JSON message as its only arguments.\n",
  22447. " try {\n",
  22448. " var callback = fig[\"handle_\" + msg_type];\n",
  22449. " } catch (e) {\n",
  22450. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  22451. " return;\n",
  22452. " }\n",
  22453. "\n",
  22454. " if (callback) {\n",
  22455. " try {\n",
  22456. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  22457. " callback(fig, msg);\n",
  22458. " } catch (e) {\n",
  22459. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  22460. " }\n",
  22461. " }\n",
  22462. " };\n",
  22463. "}\n",
  22464. "\n",
  22465. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  22466. "mpl.findpos = function(e) {\n",
  22467. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  22468. " var targ;\n",
  22469. " if (!e)\n",
  22470. " e = window.event;\n",
  22471. " if (e.target)\n",
  22472. " targ = e.target;\n",
  22473. " else if (e.srcElement)\n",
  22474. " targ = e.srcElement;\n",
  22475. " if (targ.nodeType == 3) // defeat Safari bug\n",
  22476. " targ = targ.parentNode;\n",
  22477. "\n",
  22478. " // jQuery normalizes the pageX and pageY\n",
  22479. " // pageX,Y are the mouse positions relative to the document\n",
  22480. " // offset() returns the position of the element relative to the document\n",
  22481. " var x = e.pageX - $(targ).offset().left;\n",
  22482. " var y = e.pageY - $(targ).offset().top;\n",
  22483. "\n",
  22484. " return {\"x\": x, \"y\": y};\n",
  22485. "};\n",
  22486. "\n",
  22487. "/*\n",
  22488. " * return a copy of an object with only non-object keys\n",
  22489. " * we need this to avoid circular references\n",
  22490. " * http://stackoverflow.com/a/24161582/3208463\n",
  22491. " */\n",
  22492. "function simpleKeys (original) {\n",
  22493. " return Object.keys(original).reduce(function (obj, key) {\n",
  22494. " if (typeof original[key] !== 'object')\n",
  22495. " obj[key] = original[key]\n",
  22496. " return obj;\n",
  22497. " }, {});\n",
  22498. "}\n",
  22499. "\n",
  22500. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  22501. " var canvas_pos = mpl.findpos(event)\n",
  22502. "\n",
  22503. " if (name === 'button_press')\n",
  22504. " {\n",
  22505. " this.canvas.focus();\n",
  22506. " this.canvas_div.focus();\n",
  22507. " }\n",
  22508. "\n",
  22509. " var x = canvas_pos.x * mpl.ratio;\n",
  22510. " var y = canvas_pos.y * mpl.ratio;\n",
  22511. "\n",
  22512. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  22513. " step: event.step,\n",
  22514. " guiEvent: simpleKeys(event)});\n",
  22515. "\n",
  22516. " /* This prevents the web browser from automatically changing to\n",
  22517. " * the text insertion cursor when the button is pressed. We want\n",
  22518. " * to control all of the cursor setting manually through the\n",
  22519. " * 'cursor' event from matplotlib */\n",
  22520. " event.preventDefault();\n",
  22521. " return false;\n",
  22522. "}\n",
  22523. "\n",
  22524. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  22525. " // Handle any extra behaviour associated with a key event\n",
  22526. "}\n",
  22527. "\n",
  22528. "mpl.figure.prototype.key_event = function(event, name) {\n",
  22529. "\n",
  22530. " // Prevent repeat events\n",
  22531. " if (name == 'key_press')\n",
  22532. " {\n",
  22533. " if (event.which === this._key)\n",
  22534. " return;\n",
  22535. " else\n",
  22536. " this._key = event.which;\n",
  22537. " }\n",
  22538. " if (name == 'key_release')\n",
  22539. " this._key = null;\n",
  22540. "\n",
  22541. " var value = '';\n",
  22542. " if (event.ctrlKey && event.which != 17)\n",
  22543. " value += \"ctrl+\";\n",
  22544. " if (event.altKey && event.which != 18)\n",
  22545. " value += \"alt+\";\n",
  22546. " if (event.shiftKey && event.which != 16)\n",
  22547. " value += \"shift+\";\n",
  22548. "\n",
  22549. " value += 'k';\n",
  22550. " value += event.which.toString();\n",
  22551. "\n",
  22552. " this._key_event_extra(event, name);\n",
  22553. "\n",
  22554. " this.send_message(name, {key: value,\n",
  22555. " guiEvent: simpleKeys(event)});\n",
  22556. " return false;\n",
  22557. "}\n",
  22558. "\n",
  22559. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  22560. " if (name == 'download') {\n",
  22561. " this.handle_save(this, null);\n",
  22562. " } else {\n",
  22563. " this.send_message(\"toolbar_button\", {name: name});\n",
  22564. " }\n",
  22565. "};\n",
  22566. "\n",
  22567. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  22568. " this.message.textContent = tooltip;\n",
  22569. "};\n",
  22570. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  22571. "\n",
  22572. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  22573. "\n",
  22574. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  22575. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  22576. " // object with the appropriate methods. Currently this is a non binary\n",
  22577. " // socket, so there is still some room for performance tuning.\n",
  22578. " var ws = {};\n",
  22579. "\n",
  22580. " ws.close = function() {\n",
  22581. " comm.close()\n",
  22582. " };\n",
  22583. " ws.send = function(m) {\n",
  22584. " //console.log('sending', m);\n",
  22585. " comm.send(m);\n",
  22586. " };\n",
  22587. " // Register the callback with on_msg.\n",
  22588. " comm.on_msg(function(msg) {\n",
  22589. " //console.log('receiving', msg['content']['data'], msg);\n",
  22590. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  22591. " ws.onmessage(msg['content']['data'])\n",
  22592. " });\n",
  22593. " return ws;\n",
  22594. "}\n",
  22595. "\n",
  22596. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  22597. " // This is the function which gets called when the mpl process\n",
  22598. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  22599. "\n",
  22600. " var id = msg.content.data.id;\n",
  22601. " // Get hold of the div created by the display call when the Comm\n",
  22602. " // socket was opened in Python.\n",
  22603. " var element = $(\"#\" + id);\n",
  22604. " var ws_proxy = comm_websocket_adapter(comm)\n",
  22605. "\n",
  22606. " function ondownload(figure, format) {\n",
  22607. " window.open(figure.imageObj.src);\n",
  22608. " }\n",
  22609. "\n",
  22610. " var fig = new mpl.figure(id, ws_proxy,\n",
  22611. " ondownload,\n",
  22612. " element.get(0));\n",
  22613. "\n",
  22614. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  22615. " // web socket which is closed, not our websocket->open comm proxy.\n",
  22616. " ws_proxy.onopen();\n",
  22617. "\n",
  22618. " fig.parent_element = element.get(0);\n",
  22619. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  22620. " if (!fig.cell_info) {\n",
  22621. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  22622. " return;\n",
  22623. " }\n",
  22624. "\n",
  22625. " var output_index = fig.cell_info[2]\n",
  22626. " var cell = fig.cell_info[0];\n",
  22627. "\n",
  22628. "};\n",
  22629. "\n",
  22630. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  22631. " var width = fig.canvas.width/mpl.ratio\n",
  22632. " fig.root.unbind('remove')\n",
  22633. "\n",
  22634. " // Update the output cell to use the data from the current canvas.\n",
  22635. " fig.push_to_output();\n",
  22636. " var dataURL = fig.canvas.toDataURL();\n",
  22637. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  22638. " // the notebook keyboard shortcuts fail.\n",
  22639. " IPython.keyboard_manager.enable()\n",
  22640. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  22641. " fig.close_ws(fig, msg);\n",
  22642. "}\n",
  22643. "\n",
  22644. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  22645. " fig.send_message('closing', msg);\n",
  22646. " // fig.ws.close()\n",
  22647. "}\n",
  22648. "\n",
  22649. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  22650. " // Turn the data on the canvas into data in the output cell.\n",
  22651. " var width = this.canvas.width/mpl.ratio\n",
  22652. " var dataURL = this.canvas.toDataURL();\n",
  22653. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  22654. "}\n",
  22655. "\n",
  22656. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  22657. " // Tell IPython that the notebook contents must change.\n",
  22658. " IPython.notebook.set_dirty(true);\n",
  22659. " this.send_message(\"ack\", {});\n",
  22660. " var fig = this;\n",
  22661. " // Wait a second, then push the new image to the DOM so\n",
  22662. " // that it is saved nicely (might be nice to debounce this).\n",
  22663. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  22664. "}\n",
  22665. "\n",
  22666. "mpl.figure.prototype._init_toolbar = function() {\n",
  22667. " var fig = this;\n",
  22668. "\n",
  22669. " var nav_element = $('<div/>')\n",
  22670. " nav_element.attr('style', 'width: 100%');\n",
  22671. " this.root.append(nav_element);\n",
  22672. "\n",
  22673. " // Define a callback function for later on.\n",
  22674. " function toolbar_event(event) {\n",
  22675. " return fig.toolbar_button_onclick(event['data']);\n",
  22676. " }\n",
  22677. " function toolbar_mouse_event(event) {\n",
  22678. " return fig.toolbar_button_onmouseover(event['data']);\n",
  22679. " }\n",
  22680. "\n",
  22681. " for(var toolbar_ind in mpl.toolbar_items){\n",
  22682. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  22683. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  22684. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  22685. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  22686. "\n",
  22687. " if (!name) { continue; };\n",
  22688. "\n",
  22689. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  22690. " button.click(method_name, toolbar_event);\n",
  22691. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  22692. " nav_element.append(button);\n",
  22693. " }\n",
  22694. "\n",
  22695. " // Add the status bar.\n",
  22696. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  22697. " nav_element.append(status_bar);\n",
  22698. " this.message = status_bar[0];\n",
  22699. "\n",
  22700. " // Add the close button to the window.\n",
  22701. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  22702. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  22703. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  22704. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  22705. " buttongrp.append(button);\n",
  22706. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  22707. " titlebar.prepend(buttongrp);\n",
  22708. "}\n",
  22709. "\n",
  22710. "mpl.figure.prototype._root_extra_style = function(el){\n",
  22711. " var fig = this\n",
  22712. " el.on(\"remove\", function(){\n",
  22713. "\tfig.close_ws(fig, {});\n",
  22714. " });\n",
  22715. "}\n",
  22716. "\n",
  22717. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  22718. " // this is important to make the div 'focusable\n",
  22719. " el.attr('tabindex', 0)\n",
  22720. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  22721. " // off when our div gets focus\n",
  22722. "\n",
  22723. " // location in version 3\n",
  22724. " if (IPython.notebook.keyboard_manager) {\n",
  22725. " IPython.notebook.keyboard_manager.register_events(el);\n",
  22726. " }\n",
  22727. " else {\n",
  22728. " // location in version 2\n",
  22729. " IPython.keyboard_manager.register_events(el);\n",
  22730. " }\n",
  22731. "\n",
  22732. "}\n",
  22733. "\n",
  22734. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  22735. " var manager = IPython.notebook.keyboard_manager;\n",
  22736. " if (!manager)\n",
  22737. " manager = IPython.keyboard_manager;\n",
  22738. "\n",
  22739. " // Check for shift+enter\n",
  22740. " if (event.shiftKey && event.which == 13) {\n",
  22741. " this.canvas_div.blur();\n",
  22742. " event.shiftKey = false;\n",
  22743. " // Send a \"J\" for go to next cell\n",
  22744. " event.which = 74;\n",
  22745. " event.keyCode = 74;\n",
  22746. " manager.command_mode();\n",
  22747. " manager.handle_keydown(event);\n",
  22748. " }\n",
  22749. "}\n",
  22750. "\n",
  22751. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  22752. " fig.ondownload(fig, null);\n",
  22753. "}\n",
  22754. "\n",
  22755. "\n",
  22756. "mpl.find_output_cell = function(html_output) {\n",
  22757. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  22758. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  22759. " // IPython event is triggered only after the cells have been serialised, which for\n",
  22760. " // our purposes (turning an active figure into a static one), is too late.\n",
  22761. " var cells = IPython.notebook.get_cells();\n",
  22762. " var ncells = cells.length;\n",
  22763. " for (var i=0; i<ncells; i++) {\n",
  22764. " var cell = cells[i];\n",
  22765. " if (cell.cell_type === 'code'){\n",
  22766. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  22767. " var data = cell.output_area.outputs[j];\n",
  22768. " if (data.data) {\n",
  22769. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  22770. " data = data.data;\n",
  22771. " }\n",
  22772. " if (data['text/html'] == html_output) {\n",
  22773. " return [cell, data, j];\n",
  22774. " }\n",
  22775. " }\n",
  22776. " }\n",
  22777. " }\n",
  22778. "}\n",
  22779. "\n",
  22780. "// Register the function which deals with the matplotlib target/channel.\n",
  22781. "// The kernel may be null if the page has been refreshed.\n",
  22782. "if (IPython.notebook.kernel != null) {\n",
  22783. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  22784. "}\n"
  22785. ],
  22786. "text/plain": [
  22787. "<IPython.core.display.Javascript object>"
  22788. ]
  22789. },
  22790. "metadata": {},
  22791. "output_type": "display_data"
  22792. },
  22793. {
  22794. "data": {
  22795. "text/html": [
  22796. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  22797. ],
  22798. "text/plain": [
  22799. "<IPython.core.display.HTML object>"
  22800. ]
  22801. },
  22802. "metadata": {},
  22803. "output_type": "display_data"
  22804. },
  22805. {
  22806. "name": "stdout",
  22807. "output_type": "stream",
  22808. "text": [
  22809. "0 1\n",
  22810. "689\n",
  22811. "(351, 315)\n",
  22812. "\n"
  22813. ]
  22814. },
  22815. {
  22816. "data": {
  22817. "application/javascript": [
  22818. "/* Put everything inside the global mpl namespace */\n",
  22819. "window.mpl = {};\n",
  22820. "\n",
  22821. "\n",
  22822. "mpl.get_websocket_type = function() {\n",
  22823. " if (typeof(WebSocket) !== 'undefined') {\n",
  22824. " return WebSocket;\n",
  22825. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  22826. " return MozWebSocket;\n",
  22827. " } else {\n",
  22828. " alert('Your browser does not have WebSocket support.' +\n",
  22829. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  22830. " 'Firefox 4 and 5 are also supported but you ' +\n",
  22831. " 'have to enable WebSockets in about:config.');\n",
  22832. " };\n",
  22833. "}\n",
  22834. "\n",
  22835. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  22836. " this.id = figure_id;\n",
  22837. "\n",
  22838. " this.ws = websocket;\n",
  22839. "\n",
  22840. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  22841. "\n",
  22842. " if (!this.supports_binary) {\n",
  22843. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  22844. " if (warnings) {\n",
  22845. " warnings.style.display = 'block';\n",
  22846. " warnings.textContent = (\n",
  22847. " \"This browser does not support binary websocket messages. \" +\n",
  22848. " \"Performance may be slow.\");\n",
  22849. " }\n",
  22850. " }\n",
  22851. "\n",
  22852. " this.imageObj = new Image();\n",
  22853. "\n",
  22854. " this.context = undefined;\n",
  22855. " this.message = undefined;\n",
  22856. " this.canvas = undefined;\n",
  22857. " this.rubberband_canvas = undefined;\n",
  22858. " this.rubberband_context = undefined;\n",
  22859. " this.format_dropdown = undefined;\n",
  22860. "\n",
  22861. " this.image_mode = 'full';\n",
  22862. "\n",
  22863. " this.root = $('<div/>');\n",
  22864. " this._root_extra_style(this.root)\n",
  22865. " this.root.attr('style', 'display: inline-block');\n",
  22866. "\n",
  22867. " $(parent_element).append(this.root);\n",
  22868. "\n",
  22869. " this._init_header(this);\n",
  22870. " this._init_canvas(this);\n",
  22871. " this._init_toolbar(this);\n",
  22872. "\n",
  22873. " var fig = this;\n",
  22874. "\n",
  22875. " this.waiting = false;\n",
  22876. "\n",
  22877. " this.ws.onopen = function () {\n",
  22878. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  22879. " fig.send_message(\"send_image_mode\", {});\n",
  22880. " if (mpl.ratio != 1) {\n",
  22881. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  22882. " }\n",
  22883. " fig.send_message(\"refresh\", {});\n",
  22884. " }\n",
  22885. "\n",
  22886. " this.imageObj.onload = function() {\n",
  22887. " if (fig.image_mode == 'full') {\n",
  22888. " // Full images could contain transparency (where diff images\n",
  22889. " // almost always do), so we need to clear the canvas so that\n",
  22890. " // there is no ghosting.\n",
  22891. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  22892. " }\n",
  22893. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  22894. " };\n",
  22895. "\n",
  22896. " this.imageObj.onunload = function() {\n",
  22897. " fig.ws.close();\n",
  22898. " }\n",
  22899. "\n",
  22900. " this.ws.onmessage = this._make_on_message_function(this);\n",
  22901. "\n",
  22902. " this.ondownload = ondownload;\n",
  22903. "}\n",
  22904. "\n",
  22905. "mpl.figure.prototype._init_header = function() {\n",
  22906. " var titlebar = $(\n",
  22907. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  22908. " 'ui-helper-clearfix\"/>');\n",
  22909. " var titletext = $(\n",
  22910. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  22911. " 'text-align: center; padding: 3px;\"/>');\n",
  22912. " titlebar.append(titletext)\n",
  22913. " this.root.append(titlebar);\n",
  22914. " this.header = titletext[0];\n",
  22915. "}\n",
  22916. "\n",
  22917. "\n",
  22918. "\n",
  22919. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  22920. "\n",
  22921. "}\n",
  22922. "\n",
  22923. "\n",
  22924. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  22925. "\n",
  22926. "}\n",
  22927. "\n",
  22928. "mpl.figure.prototype._init_canvas = function() {\n",
  22929. " var fig = this;\n",
  22930. "\n",
  22931. " var canvas_div = $('<div/>');\n",
  22932. "\n",
  22933. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  22934. "\n",
  22935. " function canvas_keyboard_event(event) {\n",
  22936. " return fig.key_event(event, event['data']);\n",
  22937. " }\n",
  22938. "\n",
  22939. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  22940. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  22941. " this.canvas_div = canvas_div\n",
  22942. " this._canvas_extra_style(canvas_div)\n",
  22943. " this.root.append(canvas_div);\n",
  22944. "\n",
  22945. " var canvas = $('<canvas/>');\n",
  22946. " canvas.addClass('mpl-canvas');\n",
  22947. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  22948. "\n",
  22949. " this.canvas = canvas[0];\n",
  22950. " this.context = canvas[0].getContext(\"2d\");\n",
  22951. "\n",
  22952. " var backingStore = this.context.backingStorePixelRatio ||\n",
  22953. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  22954. "\tthis.context.mozBackingStorePixelRatio ||\n",
  22955. "\tthis.context.msBackingStorePixelRatio ||\n",
  22956. "\tthis.context.oBackingStorePixelRatio ||\n",
  22957. "\tthis.context.backingStorePixelRatio || 1;\n",
  22958. "\n",
  22959. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  22960. "\n",
  22961. " var rubberband = $('<canvas/>');\n",
  22962. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  22963. "\n",
  22964. " var pass_mouse_events = true;\n",
  22965. "\n",
  22966. " canvas_div.resizable({\n",
  22967. " start: function(event, ui) {\n",
  22968. " pass_mouse_events = false;\n",
  22969. " },\n",
  22970. " resize: function(event, ui) {\n",
  22971. " fig.request_resize(ui.size.width, ui.size.height);\n",
  22972. " },\n",
  22973. " stop: function(event, ui) {\n",
  22974. " pass_mouse_events = true;\n",
  22975. " fig.request_resize(ui.size.width, ui.size.height);\n",
  22976. " },\n",
  22977. " });\n",
  22978. "\n",
  22979. " function mouse_event_fn(event) {\n",
  22980. " if (pass_mouse_events)\n",
  22981. " return fig.mouse_event(event, event['data']);\n",
  22982. " }\n",
  22983. "\n",
  22984. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  22985. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  22986. " // Throttle sequential mouse events to 1 every 20ms.\n",
  22987. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  22988. "\n",
  22989. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  22990. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  22991. "\n",
  22992. " canvas_div.on(\"wheel\", function (event) {\n",
  22993. " event = event.originalEvent;\n",
  22994. " event['data'] = 'scroll'\n",
  22995. " if (event.deltaY < 0) {\n",
  22996. " event.step = 1;\n",
  22997. " } else {\n",
  22998. " event.step = -1;\n",
  22999. " }\n",
  23000. " mouse_event_fn(event);\n",
  23001. " });\n",
  23002. "\n",
  23003. " canvas_div.append(canvas);\n",
  23004. " canvas_div.append(rubberband);\n",
  23005. "\n",
  23006. " this.rubberband = rubberband;\n",
  23007. " this.rubberband_canvas = rubberband[0];\n",
  23008. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  23009. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  23010. "\n",
  23011. " this._resize_canvas = function(width, height) {\n",
  23012. " // Keep the size of the canvas, canvas container, and rubber band\n",
  23013. " // canvas in synch.\n",
  23014. " canvas_div.css('width', width)\n",
  23015. " canvas_div.css('height', height)\n",
  23016. "\n",
  23017. " canvas.attr('width', width * mpl.ratio);\n",
  23018. " canvas.attr('height', height * mpl.ratio);\n",
  23019. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  23020. "\n",
  23021. " rubberband.attr('width', width);\n",
  23022. " rubberband.attr('height', height);\n",
  23023. " }\n",
  23024. "\n",
  23025. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  23026. " // upon first draw.\n",
  23027. " this._resize_canvas(600, 600);\n",
  23028. "\n",
  23029. " // Disable right mouse context menu.\n",
  23030. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  23031. " return false;\n",
  23032. " });\n",
  23033. "\n",
  23034. " function set_focus () {\n",
  23035. " canvas.focus();\n",
  23036. " canvas_div.focus();\n",
  23037. " }\n",
  23038. "\n",
  23039. " window.setTimeout(set_focus, 100);\n",
  23040. "}\n",
  23041. "\n",
  23042. "mpl.figure.prototype._init_toolbar = function() {\n",
  23043. " var fig = this;\n",
  23044. "\n",
  23045. " var nav_element = $('<div/>')\n",
  23046. " nav_element.attr('style', 'width: 100%');\n",
  23047. " this.root.append(nav_element);\n",
  23048. "\n",
  23049. " // Define a callback function for later on.\n",
  23050. " function toolbar_event(event) {\n",
  23051. " return fig.toolbar_button_onclick(event['data']);\n",
  23052. " }\n",
  23053. " function toolbar_mouse_event(event) {\n",
  23054. " return fig.toolbar_button_onmouseover(event['data']);\n",
  23055. " }\n",
  23056. "\n",
  23057. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  23058. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  23059. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  23060. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  23061. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  23062. "\n",
  23063. " if (!name) {\n",
  23064. " // put a spacer in here.\n",
  23065. " continue;\n",
  23066. " }\n",
  23067. " var button = $('<button/>');\n",
  23068. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  23069. " 'ui-button-icon-only');\n",
  23070. " button.attr('role', 'button');\n",
  23071. " button.attr('aria-disabled', 'false');\n",
  23072. " button.click(method_name, toolbar_event);\n",
  23073. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  23074. "\n",
  23075. " var icon_img = $('<span/>');\n",
  23076. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  23077. " icon_img.addClass(image);\n",
  23078. " icon_img.addClass('ui-corner-all');\n",
  23079. "\n",
  23080. " var tooltip_span = $('<span/>');\n",
  23081. " tooltip_span.addClass('ui-button-text');\n",
  23082. " tooltip_span.html(tooltip);\n",
  23083. "\n",
  23084. " button.append(icon_img);\n",
  23085. " button.append(tooltip_span);\n",
  23086. "\n",
  23087. " nav_element.append(button);\n",
  23088. " }\n",
  23089. "\n",
  23090. " var fmt_picker_span = $('<span/>');\n",
  23091. "\n",
  23092. " var fmt_picker = $('<select/>');\n",
  23093. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  23094. " fmt_picker_span.append(fmt_picker);\n",
  23095. " nav_element.append(fmt_picker_span);\n",
  23096. " this.format_dropdown = fmt_picker[0];\n",
  23097. "\n",
  23098. " for (var ind in mpl.extensions) {\n",
  23099. " var fmt = mpl.extensions[ind];\n",
  23100. " var option = $(\n",
  23101. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  23102. " fmt_picker.append(option)\n",
  23103. " }\n",
  23104. "\n",
  23105. " // Add hover states to the ui-buttons\n",
  23106. " $( \".ui-button\" ).hover(\n",
  23107. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  23108. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  23109. " );\n",
  23110. "\n",
  23111. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  23112. " nav_element.append(status_bar);\n",
  23113. " this.message = status_bar[0];\n",
  23114. "}\n",
  23115. "\n",
  23116. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  23117. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  23118. " // which will in turn request a refresh of the image.\n",
  23119. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  23120. "}\n",
  23121. "\n",
  23122. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  23123. " properties['type'] = type;\n",
  23124. " properties['figure_id'] = this.id;\n",
  23125. " this.ws.send(JSON.stringify(properties));\n",
  23126. "}\n",
  23127. "\n",
  23128. "mpl.figure.prototype.send_draw_message = function() {\n",
  23129. " if (!this.waiting) {\n",
  23130. " this.waiting = true;\n",
  23131. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  23132. " }\n",
  23133. "}\n",
  23134. "\n",
  23135. "\n",
  23136. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  23137. " var format_dropdown = fig.format_dropdown;\n",
  23138. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  23139. " fig.ondownload(fig, format);\n",
  23140. "}\n",
  23141. "\n",
  23142. "\n",
  23143. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  23144. " var size = msg['size'];\n",
  23145. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  23146. " fig._resize_canvas(size[0], size[1]);\n",
  23147. " fig.send_message(\"refresh\", {});\n",
  23148. " };\n",
  23149. "}\n",
  23150. "\n",
  23151. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  23152. " var x0 = msg['x0'] / mpl.ratio;\n",
  23153. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  23154. " var x1 = msg['x1'] / mpl.ratio;\n",
  23155. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  23156. " x0 = Math.floor(x0) + 0.5;\n",
  23157. " y0 = Math.floor(y0) + 0.5;\n",
  23158. " x1 = Math.floor(x1) + 0.5;\n",
  23159. " y1 = Math.floor(y1) + 0.5;\n",
  23160. " var min_x = Math.min(x0, x1);\n",
  23161. " var min_y = Math.min(y0, y1);\n",
  23162. " var width = Math.abs(x1 - x0);\n",
  23163. " var height = Math.abs(y1 - y0);\n",
  23164. "\n",
  23165. " fig.rubberband_context.clearRect(\n",
  23166. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  23167. "\n",
  23168. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  23169. "}\n",
  23170. "\n",
  23171. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  23172. " // Updates the figure title.\n",
  23173. " fig.header.textContent = msg['label'];\n",
  23174. "}\n",
  23175. "\n",
  23176. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  23177. " var cursor = msg['cursor'];\n",
  23178. " switch(cursor)\n",
  23179. " {\n",
  23180. " case 0:\n",
  23181. " cursor = 'pointer';\n",
  23182. " break;\n",
  23183. " case 1:\n",
  23184. " cursor = 'default';\n",
  23185. " break;\n",
  23186. " case 2:\n",
  23187. " cursor = 'crosshair';\n",
  23188. " break;\n",
  23189. " case 3:\n",
  23190. " cursor = 'move';\n",
  23191. " break;\n",
  23192. " }\n",
  23193. " fig.rubberband_canvas.style.cursor = cursor;\n",
  23194. "}\n",
  23195. "\n",
  23196. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  23197. " fig.message.textContent = msg['message'];\n",
  23198. "}\n",
  23199. "\n",
  23200. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  23201. " // Request the server to send over a new figure.\n",
  23202. " fig.send_draw_message();\n",
  23203. "}\n",
  23204. "\n",
  23205. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  23206. " fig.image_mode = msg['mode'];\n",
  23207. "}\n",
  23208. "\n",
  23209. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  23210. " // Called whenever the canvas gets updated.\n",
  23211. " this.send_message(\"ack\", {});\n",
  23212. "}\n",
  23213. "\n",
  23214. "// A function to construct a web socket function for onmessage handling.\n",
  23215. "// Called in the figure constructor.\n",
  23216. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  23217. " return function socket_on_message(evt) {\n",
  23218. " if (evt.data instanceof Blob) {\n",
  23219. " /* FIXME: We get \"Resource interpreted as Image but\n",
  23220. " * transferred with MIME type text/plain:\" errors on\n",
  23221. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  23222. " * to be part of the websocket stream */\n",
  23223. " evt.data.type = \"image/png\";\n",
  23224. "\n",
  23225. " /* Free the memory for the previous frames */\n",
  23226. " if (fig.imageObj.src) {\n",
  23227. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  23228. " fig.imageObj.src);\n",
  23229. " }\n",
  23230. "\n",
  23231. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  23232. " evt.data);\n",
  23233. " fig.updated_canvas_event();\n",
  23234. " fig.waiting = false;\n",
  23235. " return;\n",
  23236. " }\n",
  23237. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  23238. " fig.imageObj.src = evt.data;\n",
  23239. " fig.updated_canvas_event();\n",
  23240. " fig.waiting = false;\n",
  23241. " return;\n",
  23242. " }\n",
  23243. "\n",
  23244. " var msg = JSON.parse(evt.data);\n",
  23245. " var msg_type = msg['type'];\n",
  23246. "\n",
  23247. " // Call the \"handle_{type}\" callback, which takes\n",
  23248. " // the figure and JSON message as its only arguments.\n",
  23249. " try {\n",
  23250. " var callback = fig[\"handle_\" + msg_type];\n",
  23251. " } catch (e) {\n",
  23252. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  23253. " return;\n",
  23254. " }\n",
  23255. "\n",
  23256. " if (callback) {\n",
  23257. " try {\n",
  23258. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  23259. " callback(fig, msg);\n",
  23260. " } catch (e) {\n",
  23261. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  23262. " }\n",
  23263. " }\n",
  23264. " };\n",
  23265. "}\n",
  23266. "\n",
  23267. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  23268. "mpl.findpos = function(e) {\n",
  23269. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  23270. " var targ;\n",
  23271. " if (!e)\n",
  23272. " e = window.event;\n",
  23273. " if (e.target)\n",
  23274. " targ = e.target;\n",
  23275. " else if (e.srcElement)\n",
  23276. " targ = e.srcElement;\n",
  23277. " if (targ.nodeType == 3) // defeat Safari bug\n",
  23278. " targ = targ.parentNode;\n",
  23279. "\n",
  23280. " // jQuery normalizes the pageX and pageY\n",
  23281. " // pageX,Y are the mouse positions relative to the document\n",
  23282. " // offset() returns the position of the element relative to the document\n",
  23283. " var x = e.pageX - $(targ).offset().left;\n",
  23284. " var y = e.pageY - $(targ).offset().top;\n",
  23285. "\n",
  23286. " return {\"x\": x, \"y\": y};\n",
  23287. "};\n",
  23288. "\n",
  23289. "/*\n",
  23290. " * return a copy of an object with only non-object keys\n",
  23291. " * we need this to avoid circular references\n",
  23292. " * http://stackoverflow.com/a/24161582/3208463\n",
  23293. " */\n",
  23294. "function simpleKeys (original) {\n",
  23295. " return Object.keys(original).reduce(function (obj, key) {\n",
  23296. " if (typeof original[key] !== 'object')\n",
  23297. " obj[key] = original[key]\n",
  23298. " return obj;\n",
  23299. " }, {});\n",
  23300. "}\n",
  23301. "\n",
  23302. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  23303. " var canvas_pos = mpl.findpos(event)\n",
  23304. "\n",
  23305. " if (name === 'button_press')\n",
  23306. " {\n",
  23307. " this.canvas.focus();\n",
  23308. " this.canvas_div.focus();\n",
  23309. " }\n",
  23310. "\n",
  23311. " var x = canvas_pos.x * mpl.ratio;\n",
  23312. " var y = canvas_pos.y * mpl.ratio;\n",
  23313. "\n",
  23314. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  23315. " step: event.step,\n",
  23316. " guiEvent: simpleKeys(event)});\n",
  23317. "\n",
  23318. " /* This prevents the web browser from automatically changing to\n",
  23319. " * the text insertion cursor when the button is pressed. We want\n",
  23320. " * to control all of the cursor setting manually through the\n",
  23321. " * 'cursor' event from matplotlib */\n",
  23322. " event.preventDefault();\n",
  23323. " return false;\n",
  23324. "}\n",
  23325. "\n",
  23326. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  23327. " // Handle any extra behaviour associated with a key event\n",
  23328. "}\n",
  23329. "\n",
  23330. "mpl.figure.prototype.key_event = function(event, name) {\n",
  23331. "\n",
  23332. " // Prevent repeat events\n",
  23333. " if (name == 'key_press')\n",
  23334. " {\n",
  23335. " if (event.which === this._key)\n",
  23336. " return;\n",
  23337. " else\n",
  23338. " this._key = event.which;\n",
  23339. " }\n",
  23340. " if (name == 'key_release')\n",
  23341. " this._key = null;\n",
  23342. "\n",
  23343. " var value = '';\n",
  23344. " if (event.ctrlKey && event.which != 17)\n",
  23345. " value += \"ctrl+\";\n",
  23346. " if (event.altKey && event.which != 18)\n",
  23347. " value += \"alt+\";\n",
  23348. " if (event.shiftKey && event.which != 16)\n",
  23349. " value += \"shift+\";\n",
  23350. "\n",
  23351. " value += 'k';\n",
  23352. " value += event.which.toString();\n",
  23353. "\n",
  23354. " this._key_event_extra(event, name);\n",
  23355. "\n",
  23356. " this.send_message(name, {key: value,\n",
  23357. " guiEvent: simpleKeys(event)});\n",
  23358. " return false;\n",
  23359. "}\n",
  23360. "\n",
  23361. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  23362. " if (name == 'download') {\n",
  23363. " this.handle_save(this, null);\n",
  23364. " } else {\n",
  23365. " this.send_message(\"toolbar_button\", {name: name});\n",
  23366. " }\n",
  23367. "};\n",
  23368. "\n",
  23369. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  23370. " this.message.textContent = tooltip;\n",
  23371. "};\n",
  23372. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  23373. "\n",
  23374. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  23375. "\n",
  23376. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  23377. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  23378. " // object with the appropriate methods. Currently this is a non binary\n",
  23379. " // socket, so there is still some room for performance tuning.\n",
  23380. " var ws = {};\n",
  23381. "\n",
  23382. " ws.close = function() {\n",
  23383. " comm.close()\n",
  23384. " };\n",
  23385. " ws.send = function(m) {\n",
  23386. " //console.log('sending', m);\n",
  23387. " comm.send(m);\n",
  23388. " };\n",
  23389. " // Register the callback with on_msg.\n",
  23390. " comm.on_msg(function(msg) {\n",
  23391. " //console.log('receiving', msg['content']['data'], msg);\n",
  23392. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  23393. " ws.onmessage(msg['content']['data'])\n",
  23394. " });\n",
  23395. " return ws;\n",
  23396. "}\n",
  23397. "\n",
  23398. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  23399. " // This is the function which gets called when the mpl process\n",
  23400. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  23401. "\n",
  23402. " var id = msg.content.data.id;\n",
  23403. " // Get hold of the div created by the display call when the Comm\n",
  23404. " // socket was opened in Python.\n",
  23405. " var element = $(\"#\" + id);\n",
  23406. " var ws_proxy = comm_websocket_adapter(comm)\n",
  23407. "\n",
  23408. " function ondownload(figure, format) {\n",
  23409. " window.open(figure.imageObj.src);\n",
  23410. " }\n",
  23411. "\n",
  23412. " var fig = new mpl.figure(id, ws_proxy,\n",
  23413. " ondownload,\n",
  23414. " element.get(0));\n",
  23415. "\n",
  23416. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  23417. " // web socket which is closed, not our websocket->open comm proxy.\n",
  23418. " ws_proxy.onopen();\n",
  23419. "\n",
  23420. " fig.parent_element = element.get(0);\n",
  23421. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  23422. " if (!fig.cell_info) {\n",
  23423. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  23424. " return;\n",
  23425. " }\n",
  23426. "\n",
  23427. " var output_index = fig.cell_info[2]\n",
  23428. " var cell = fig.cell_info[0];\n",
  23429. "\n",
  23430. "};\n",
  23431. "\n",
  23432. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  23433. " var width = fig.canvas.width/mpl.ratio\n",
  23434. " fig.root.unbind('remove')\n",
  23435. "\n",
  23436. " // Update the output cell to use the data from the current canvas.\n",
  23437. " fig.push_to_output();\n",
  23438. " var dataURL = fig.canvas.toDataURL();\n",
  23439. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  23440. " // the notebook keyboard shortcuts fail.\n",
  23441. " IPython.keyboard_manager.enable()\n",
  23442. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  23443. " fig.close_ws(fig, msg);\n",
  23444. "}\n",
  23445. "\n",
  23446. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  23447. " fig.send_message('closing', msg);\n",
  23448. " // fig.ws.close()\n",
  23449. "}\n",
  23450. "\n",
  23451. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  23452. " // Turn the data on the canvas into data in the output cell.\n",
  23453. " var width = this.canvas.width/mpl.ratio\n",
  23454. " var dataURL = this.canvas.toDataURL();\n",
  23455. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  23456. "}\n",
  23457. "\n",
  23458. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  23459. " // Tell IPython that the notebook contents must change.\n",
  23460. " IPython.notebook.set_dirty(true);\n",
  23461. " this.send_message(\"ack\", {});\n",
  23462. " var fig = this;\n",
  23463. " // Wait a second, then push the new image to the DOM so\n",
  23464. " // that it is saved nicely (might be nice to debounce this).\n",
  23465. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  23466. "}\n",
  23467. "\n",
  23468. "mpl.figure.prototype._init_toolbar = function() {\n",
  23469. " var fig = this;\n",
  23470. "\n",
  23471. " var nav_element = $('<div/>')\n",
  23472. " nav_element.attr('style', 'width: 100%');\n",
  23473. " this.root.append(nav_element);\n",
  23474. "\n",
  23475. " // Define a callback function for later on.\n",
  23476. " function toolbar_event(event) {\n",
  23477. " return fig.toolbar_button_onclick(event['data']);\n",
  23478. " }\n",
  23479. " function toolbar_mouse_event(event) {\n",
  23480. " return fig.toolbar_button_onmouseover(event['data']);\n",
  23481. " }\n",
  23482. "\n",
  23483. " for(var toolbar_ind in mpl.toolbar_items){\n",
  23484. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  23485. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  23486. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  23487. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  23488. "\n",
  23489. " if (!name) { continue; };\n",
  23490. "\n",
  23491. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  23492. " button.click(method_name, toolbar_event);\n",
  23493. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  23494. " nav_element.append(button);\n",
  23495. " }\n",
  23496. "\n",
  23497. " // Add the status bar.\n",
  23498. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  23499. " nav_element.append(status_bar);\n",
  23500. " this.message = status_bar[0];\n",
  23501. "\n",
  23502. " // Add the close button to the window.\n",
  23503. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  23504. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  23505. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  23506. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  23507. " buttongrp.append(button);\n",
  23508. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  23509. " titlebar.prepend(buttongrp);\n",
  23510. "}\n",
  23511. "\n",
  23512. "mpl.figure.prototype._root_extra_style = function(el){\n",
  23513. " var fig = this\n",
  23514. " el.on(\"remove\", function(){\n",
  23515. "\tfig.close_ws(fig, {});\n",
  23516. " });\n",
  23517. "}\n",
  23518. "\n",
  23519. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  23520. " // this is important to make the div 'focusable\n",
  23521. " el.attr('tabindex', 0)\n",
  23522. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  23523. " // off when our div gets focus\n",
  23524. "\n",
  23525. " // location in version 3\n",
  23526. " if (IPython.notebook.keyboard_manager) {\n",
  23527. " IPython.notebook.keyboard_manager.register_events(el);\n",
  23528. " }\n",
  23529. " else {\n",
  23530. " // location in version 2\n",
  23531. " IPython.keyboard_manager.register_events(el);\n",
  23532. " }\n",
  23533. "\n",
  23534. "}\n",
  23535. "\n",
  23536. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  23537. " var manager = IPython.notebook.keyboard_manager;\n",
  23538. " if (!manager)\n",
  23539. " manager = IPython.keyboard_manager;\n",
  23540. "\n",
  23541. " // Check for shift+enter\n",
  23542. " if (event.shiftKey && event.which == 13) {\n",
  23543. " this.canvas_div.blur();\n",
  23544. " event.shiftKey = false;\n",
  23545. " // Send a \"J\" for go to next cell\n",
  23546. " event.which = 74;\n",
  23547. " event.keyCode = 74;\n",
  23548. " manager.command_mode();\n",
  23549. " manager.handle_keydown(event);\n",
  23550. " }\n",
  23551. "}\n",
  23552. "\n",
  23553. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  23554. " fig.ondownload(fig, null);\n",
  23555. "}\n",
  23556. "\n",
  23557. "\n",
  23558. "mpl.find_output_cell = function(html_output) {\n",
  23559. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  23560. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  23561. " // IPython event is triggered only after the cells have been serialised, which for\n",
  23562. " // our purposes (turning an active figure into a static one), is too late.\n",
  23563. " var cells = IPython.notebook.get_cells();\n",
  23564. " var ncells = cells.length;\n",
  23565. " for (var i=0; i<ncells; i++) {\n",
  23566. " var cell = cells[i];\n",
  23567. " if (cell.cell_type === 'code'){\n",
  23568. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  23569. " var data = cell.output_area.outputs[j];\n",
  23570. " if (data.data) {\n",
  23571. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  23572. " data = data.data;\n",
  23573. " }\n",
  23574. " if (data['text/html'] == html_output) {\n",
  23575. " return [cell, data, j];\n",
  23576. " }\n",
  23577. " }\n",
  23578. " }\n",
  23579. " }\n",
  23580. "}\n",
  23581. "\n",
  23582. "// Register the function which deals with the matplotlib target/channel.\n",
  23583. "// The kernel may be null if the page has been refreshed.\n",
  23584. "if (IPython.notebook.kernel != null) {\n",
  23585. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  23586. "}\n"
  23587. ],
  23588. "text/plain": [
  23589. "<IPython.core.display.Javascript object>"
  23590. ]
  23591. },
  23592. "metadata": {},
  23593. "output_type": "display_data"
  23594. },
  23595. {
  23596. "data": {
  23597. "text/html": [
  23598. "<img src=\"data:image/png;base64,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JDcmeWi83+1JTpnye1wznt+bZFeSnRmednhoysc/HgaYJKk6AwxgcSxlGEKz2j3lPq9PckeS7yd5NskDSd6d5LQVfp8rMjw98ZkMrxW7L8n2OTz+xACTJJVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAEshnOSXJXk00keTvJskqeT3J3k95KcOuN+lya5I8mT432+muTaJKet8HtdnuTO8ePvT3Jvku3r/QRGBpgkqToDDGAx/H6SQ0keTfK3Sd6f5JYkT43HP5XklGX3eXOSgxlG1CeT3JTkofH2t8/4fa4ez+9NsivJziR7xmM75vB5GGCSpOoMMIDFcFmSK3L0d7p+Lsn/ZBhIvzVx/Mwk30vyfJLXTRw/I8kX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\" width=\"432\">"
  23599. ],
  23600. "text/plain": [
  23601. "<IPython.core.display.HTML object>"
  23602. ]
  23603. },
  23604. "metadata": {},
  23605. "output_type": "display_data"
  23606. },
  23607. {
  23608. "name": "stdout",
  23609. "output_type": "stream",
  23610. "text": [
  23611. "0.0 0.9999968\n",
  23612. "666.42615\n",
  23613. "(369, 318)\n",
  23614. "\n"
  23615. ]
  23616. },
  23617. {
  23618. "data": {
  23619. "application/javascript": [
  23620. "/* Put everything inside the global mpl namespace */\n",
  23621. "window.mpl = {};\n",
  23622. "\n",
  23623. "\n",
  23624. "mpl.get_websocket_type = function() {\n",
  23625. " if (typeof(WebSocket) !== 'undefined') {\n",
  23626. " return WebSocket;\n",
  23627. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  23628. " return MozWebSocket;\n",
  23629. " } else {\n",
  23630. " alert('Your browser does not have WebSocket support.' +\n",
  23631. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  23632. " 'Firefox 4 and 5 are also supported but you ' +\n",
  23633. " 'have to enable WebSockets in about:config.');\n",
  23634. " };\n",
  23635. "}\n",
  23636. "\n",
  23637. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  23638. " this.id = figure_id;\n",
  23639. "\n",
  23640. " this.ws = websocket;\n",
  23641. "\n",
  23642. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  23643. "\n",
  23644. " if (!this.supports_binary) {\n",
  23645. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  23646. " if (warnings) {\n",
  23647. " warnings.style.display = 'block';\n",
  23648. " warnings.textContent = (\n",
  23649. " \"This browser does not support binary websocket messages. \" +\n",
  23650. " \"Performance may be slow.\");\n",
  23651. " }\n",
  23652. " }\n",
  23653. "\n",
  23654. " this.imageObj = new Image();\n",
  23655. "\n",
  23656. " this.context = undefined;\n",
  23657. " this.message = undefined;\n",
  23658. " this.canvas = undefined;\n",
  23659. " this.rubberband_canvas = undefined;\n",
  23660. " this.rubberband_context = undefined;\n",
  23661. " this.format_dropdown = undefined;\n",
  23662. "\n",
  23663. " this.image_mode = 'full';\n",
  23664. "\n",
  23665. " this.root = $('<div/>');\n",
  23666. " this._root_extra_style(this.root)\n",
  23667. " this.root.attr('style', 'display: inline-block');\n",
  23668. "\n",
  23669. " $(parent_element).append(this.root);\n",
  23670. "\n",
  23671. " this._init_header(this);\n",
  23672. " this._init_canvas(this);\n",
  23673. " this._init_toolbar(this);\n",
  23674. "\n",
  23675. " var fig = this;\n",
  23676. "\n",
  23677. " this.waiting = false;\n",
  23678. "\n",
  23679. " this.ws.onopen = function () {\n",
  23680. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  23681. " fig.send_message(\"send_image_mode\", {});\n",
  23682. " if (mpl.ratio != 1) {\n",
  23683. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  23684. " }\n",
  23685. " fig.send_message(\"refresh\", {});\n",
  23686. " }\n",
  23687. "\n",
  23688. " this.imageObj.onload = function() {\n",
  23689. " if (fig.image_mode == 'full') {\n",
  23690. " // Full images could contain transparency (where diff images\n",
  23691. " // almost always do), so we need to clear the canvas so that\n",
  23692. " // there is no ghosting.\n",
  23693. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  23694. " }\n",
  23695. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  23696. " };\n",
  23697. "\n",
  23698. " this.imageObj.onunload = function() {\n",
  23699. " fig.ws.close();\n",
  23700. " }\n",
  23701. "\n",
  23702. " this.ws.onmessage = this._make_on_message_function(this);\n",
  23703. "\n",
  23704. " this.ondownload = ondownload;\n",
  23705. "}\n",
  23706. "\n",
  23707. "mpl.figure.prototype._init_header = function() {\n",
  23708. " var titlebar = $(\n",
  23709. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  23710. " 'ui-helper-clearfix\"/>');\n",
  23711. " var titletext = $(\n",
  23712. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  23713. " 'text-align: center; padding: 3px;\"/>');\n",
  23714. " titlebar.append(titletext)\n",
  23715. " this.root.append(titlebar);\n",
  23716. " this.header = titletext[0];\n",
  23717. "}\n",
  23718. "\n",
  23719. "\n",
  23720. "\n",
  23721. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  23722. "\n",
  23723. "}\n",
  23724. "\n",
  23725. "\n",
  23726. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  23727. "\n",
  23728. "}\n",
  23729. "\n",
  23730. "mpl.figure.prototype._init_canvas = function() {\n",
  23731. " var fig = this;\n",
  23732. "\n",
  23733. " var canvas_div = $('<div/>');\n",
  23734. "\n",
  23735. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  23736. "\n",
  23737. " function canvas_keyboard_event(event) {\n",
  23738. " return fig.key_event(event, event['data']);\n",
  23739. " }\n",
  23740. "\n",
  23741. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  23742. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  23743. " this.canvas_div = canvas_div\n",
  23744. " this._canvas_extra_style(canvas_div)\n",
  23745. " this.root.append(canvas_div);\n",
  23746. "\n",
  23747. " var canvas = $('<canvas/>');\n",
  23748. " canvas.addClass('mpl-canvas');\n",
  23749. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  23750. "\n",
  23751. " this.canvas = canvas[0];\n",
  23752. " this.context = canvas[0].getContext(\"2d\");\n",
  23753. "\n",
  23754. " var backingStore = this.context.backingStorePixelRatio ||\n",
  23755. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  23756. "\tthis.context.mozBackingStorePixelRatio ||\n",
  23757. "\tthis.context.msBackingStorePixelRatio ||\n",
  23758. "\tthis.context.oBackingStorePixelRatio ||\n",
  23759. "\tthis.context.backingStorePixelRatio || 1;\n",
  23760. "\n",
  23761. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  23762. "\n",
  23763. " var rubberband = $('<canvas/>');\n",
  23764. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  23765. "\n",
  23766. " var pass_mouse_events = true;\n",
  23767. "\n",
  23768. " canvas_div.resizable({\n",
  23769. " start: function(event, ui) {\n",
  23770. " pass_mouse_events = false;\n",
  23771. " },\n",
  23772. " resize: function(event, ui) {\n",
  23773. " fig.request_resize(ui.size.width, ui.size.height);\n",
  23774. " },\n",
  23775. " stop: function(event, ui) {\n",
  23776. " pass_mouse_events = true;\n",
  23777. " fig.request_resize(ui.size.width, ui.size.height);\n",
  23778. " },\n",
  23779. " });\n",
  23780. "\n",
  23781. " function mouse_event_fn(event) {\n",
  23782. " if (pass_mouse_events)\n",
  23783. " return fig.mouse_event(event, event['data']);\n",
  23784. " }\n",
  23785. "\n",
  23786. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  23787. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  23788. " // Throttle sequential mouse events to 1 every 20ms.\n",
  23789. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  23790. "\n",
  23791. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  23792. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  23793. "\n",
  23794. " canvas_div.on(\"wheel\", function (event) {\n",
  23795. " event = event.originalEvent;\n",
  23796. " event['data'] = 'scroll'\n",
  23797. " if (event.deltaY < 0) {\n",
  23798. " event.step = 1;\n",
  23799. " } else {\n",
  23800. " event.step = -1;\n",
  23801. " }\n",
  23802. " mouse_event_fn(event);\n",
  23803. " });\n",
  23804. "\n",
  23805. " canvas_div.append(canvas);\n",
  23806. " canvas_div.append(rubberband);\n",
  23807. "\n",
  23808. " this.rubberband = rubberband;\n",
  23809. " this.rubberband_canvas = rubberband[0];\n",
  23810. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  23811. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  23812. "\n",
  23813. " this._resize_canvas = function(width, height) {\n",
  23814. " // Keep the size of the canvas, canvas container, and rubber band\n",
  23815. " // canvas in synch.\n",
  23816. " canvas_div.css('width', width)\n",
  23817. " canvas_div.css('height', height)\n",
  23818. "\n",
  23819. " canvas.attr('width', width * mpl.ratio);\n",
  23820. " canvas.attr('height', height * mpl.ratio);\n",
  23821. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  23822. "\n",
  23823. " rubberband.attr('width', width);\n",
  23824. " rubberband.attr('height', height);\n",
  23825. " }\n",
  23826. "\n",
  23827. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  23828. " // upon first draw.\n",
  23829. " this._resize_canvas(600, 600);\n",
  23830. "\n",
  23831. " // Disable right mouse context menu.\n",
  23832. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  23833. " return false;\n",
  23834. " });\n",
  23835. "\n",
  23836. " function set_focus () {\n",
  23837. " canvas.focus();\n",
  23838. " canvas_div.focus();\n",
  23839. " }\n",
  23840. "\n",
  23841. " window.setTimeout(set_focus, 100);\n",
  23842. "}\n",
  23843. "\n",
  23844. "mpl.figure.prototype._init_toolbar = function() {\n",
  23845. " var fig = this;\n",
  23846. "\n",
  23847. " var nav_element = $('<div/>')\n",
  23848. " nav_element.attr('style', 'width: 100%');\n",
  23849. " this.root.append(nav_element);\n",
  23850. "\n",
  23851. " // Define a callback function for later on.\n",
  23852. " function toolbar_event(event) {\n",
  23853. " return fig.toolbar_button_onclick(event['data']);\n",
  23854. " }\n",
  23855. " function toolbar_mouse_event(event) {\n",
  23856. " return fig.toolbar_button_onmouseover(event['data']);\n",
  23857. " }\n",
  23858. "\n",
  23859. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  23860. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  23861. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  23862. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  23863. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  23864. "\n",
  23865. " if (!name) {\n",
  23866. " // put a spacer in here.\n",
  23867. " continue;\n",
  23868. " }\n",
  23869. " var button = $('<button/>');\n",
  23870. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  23871. " 'ui-button-icon-only');\n",
  23872. " button.attr('role', 'button');\n",
  23873. " button.attr('aria-disabled', 'false');\n",
  23874. " button.click(method_name, toolbar_event);\n",
  23875. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  23876. "\n",
  23877. " var icon_img = $('<span/>');\n",
  23878. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  23879. " icon_img.addClass(image);\n",
  23880. " icon_img.addClass('ui-corner-all');\n",
  23881. "\n",
  23882. " var tooltip_span = $('<span/>');\n",
  23883. " tooltip_span.addClass('ui-button-text');\n",
  23884. " tooltip_span.html(tooltip);\n",
  23885. "\n",
  23886. " button.append(icon_img);\n",
  23887. " button.append(tooltip_span);\n",
  23888. "\n",
  23889. " nav_element.append(button);\n",
  23890. " }\n",
  23891. "\n",
  23892. " var fmt_picker_span = $('<span/>');\n",
  23893. "\n",
  23894. " var fmt_picker = $('<select/>');\n",
  23895. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  23896. " fmt_picker_span.append(fmt_picker);\n",
  23897. " nav_element.append(fmt_picker_span);\n",
  23898. " this.format_dropdown = fmt_picker[0];\n",
  23899. "\n",
  23900. " for (var ind in mpl.extensions) {\n",
  23901. " var fmt = mpl.extensions[ind];\n",
  23902. " var option = $(\n",
  23903. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  23904. " fmt_picker.append(option)\n",
  23905. " }\n",
  23906. "\n",
  23907. " // Add hover states to the ui-buttons\n",
  23908. " $( \".ui-button\" ).hover(\n",
  23909. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  23910. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  23911. " );\n",
  23912. "\n",
  23913. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  23914. " nav_element.append(status_bar);\n",
  23915. " this.message = status_bar[0];\n",
  23916. "}\n",
  23917. "\n",
  23918. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  23919. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  23920. " // which will in turn request a refresh of the image.\n",
  23921. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  23922. "}\n",
  23923. "\n",
  23924. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  23925. " properties['type'] = type;\n",
  23926. " properties['figure_id'] = this.id;\n",
  23927. " this.ws.send(JSON.stringify(properties));\n",
  23928. "}\n",
  23929. "\n",
  23930. "mpl.figure.prototype.send_draw_message = function() {\n",
  23931. " if (!this.waiting) {\n",
  23932. " this.waiting = true;\n",
  23933. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  23934. " }\n",
  23935. "}\n",
  23936. "\n",
  23937. "\n",
  23938. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  23939. " var format_dropdown = fig.format_dropdown;\n",
  23940. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  23941. " fig.ondownload(fig, format);\n",
  23942. "}\n",
  23943. "\n",
  23944. "\n",
  23945. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  23946. " var size = msg['size'];\n",
  23947. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  23948. " fig._resize_canvas(size[0], size[1]);\n",
  23949. " fig.send_message(\"refresh\", {});\n",
  23950. " };\n",
  23951. "}\n",
  23952. "\n",
  23953. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  23954. " var x0 = msg['x0'] / mpl.ratio;\n",
  23955. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  23956. " var x1 = msg['x1'] / mpl.ratio;\n",
  23957. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  23958. " x0 = Math.floor(x0) + 0.5;\n",
  23959. " y0 = Math.floor(y0) + 0.5;\n",
  23960. " x1 = Math.floor(x1) + 0.5;\n",
  23961. " y1 = Math.floor(y1) + 0.5;\n",
  23962. " var min_x = Math.min(x0, x1);\n",
  23963. " var min_y = Math.min(y0, y1);\n",
  23964. " var width = Math.abs(x1 - x0);\n",
  23965. " var height = Math.abs(y1 - y0);\n",
  23966. "\n",
  23967. " fig.rubberband_context.clearRect(\n",
  23968. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  23969. "\n",
  23970. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  23971. "}\n",
  23972. "\n",
  23973. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  23974. " // Updates the figure title.\n",
  23975. " fig.header.textContent = msg['label'];\n",
  23976. "}\n",
  23977. "\n",
  23978. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  23979. " var cursor = msg['cursor'];\n",
  23980. " switch(cursor)\n",
  23981. " {\n",
  23982. " case 0:\n",
  23983. " cursor = 'pointer';\n",
  23984. " break;\n",
  23985. " case 1:\n",
  23986. " cursor = 'default';\n",
  23987. " break;\n",
  23988. " case 2:\n",
  23989. " cursor = 'crosshair';\n",
  23990. " break;\n",
  23991. " case 3:\n",
  23992. " cursor = 'move';\n",
  23993. " break;\n",
  23994. " }\n",
  23995. " fig.rubberband_canvas.style.cursor = cursor;\n",
  23996. "}\n",
  23997. "\n",
  23998. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  23999. " fig.message.textContent = msg['message'];\n",
  24000. "}\n",
  24001. "\n",
  24002. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  24003. " // Request the server to send over a new figure.\n",
  24004. " fig.send_draw_message();\n",
  24005. "}\n",
  24006. "\n",
  24007. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  24008. " fig.image_mode = msg['mode'];\n",
  24009. "}\n",
  24010. "\n",
  24011. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  24012. " // Called whenever the canvas gets updated.\n",
  24013. " this.send_message(\"ack\", {});\n",
  24014. "}\n",
  24015. "\n",
  24016. "// A function to construct a web socket function for onmessage handling.\n",
  24017. "// Called in the figure constructor.\n",
  24018. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  24019. " return function socket_on_message(evt) {\n",
  24020. " if (evt.data instanceof Blob) {\n",
  24021. " /* FIXME: We get \"Resource interpreted as Image but\n",
  24022. " * transferred with MIME type text/plain:\" errors on\n",
  24023. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  24024. " * to be part of the websocket stream */\n",
  24025. " evt.data.type = \"image/png\";\n",
  24026. "\n",
  24027. " /* Free the memory for the previous frames */\n",
  24028. " if (fig.imageObj.src) {\n",
  24029. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  24030. " fig.imageObj.src);\n",
  24031. " }\n",
  24032. "\n",
  24033. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  24034. " evt.data);\n",
  24035. " fig.updated_canvas_event();\n",
  24036. " fig.waiting = false;\n",
  24037. " return;\n",
  24038. " }\n",
  24039. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  24040. " fig.imageObj.src = evt.data;\n",
  24041. " fig.updated_canvas_event();\n",
  24042. " fig.waiting = false;\n",
  24043. " return;\n",
  24044. " }\n",
  24045. "\n",
  24046. " var msg = JSON.parse(evt.data);\n",
  24047. " var msg_type = msg['type'];\n",
  24048. "\n",
  24049. " // Call the \"handle_{type}\" callback, which takes\n",
  24050. " // the figure and JSON message as its only arguments.\n",
  24051. " try {\n",
  24052. " var callback = fig[\"handle_\" + msg_type];\n",
  24053. " } catch (e) {\n",
  24054. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  24055. " return;\n",
  24056. " }\n",
  24057. "\n",
  24058. " if (callback) {\n",
  24059. " try {\n",
  24060. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  24061. " callback(fig, msg);\n",
  24062. " } catch (e) {\n",
  24063. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  24064. " }\n",
  24065. " }\n",
  24066. " };\n",
  24067. "}\n",
  24068. "\n",
  24069. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  24070. "mpl.findpos = function(e) {\n",
  24071. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  24072. " var targ;\n",
  24073. " if (!e)\n",
  24074. " e = window.event;\n",
  24075. " if (e.target)\n",
  24076. " targ = e.target;\n",
  24077. " else if (e.srcElement)\n",
  24078. " targ = e.srcElement;\n",
  24079. " if (targ.nodeType == 3) // defeat Safari bug\n",
  24080. " targ = targ.parentNode;\n",
  24081. "\n",
  24082. " // jQuery normalizes the pageX and pageY\n",
  24083. " // pageX,Y are the mouse positions relative to the document\n",
  24084. " // offset() returns the position of the element relative to the document\n",
  24085. " var x = e.pageX - $(targ).offset().left;\n",
  24086. " var y = e.pageY - $(targ).offset().top;\n",
  24087. "\n",
  24088. " return {\"x\": x, \"y\": y};\n",
  24089. "};\n",
  24090. "\n",
  24091. "/*\n",
  24092. " * return a copy of an object with only non-object keys\n",
  24093. " * we need this to avoid circular references\n",
  24094. " * http://stackoverflow.com/a/24161582/3208463\n",
  24095. " */\n",
  24096. "function simpleKeys (original) {\n",
  24097. " return Object.keys(original).reduce(function (obj, key) {\n",
  24098. " if (typeof original[key] !== 'object')\n",
  24099. " obj[key] = original[key]\n",
  24100. " return obj;\n",
  24101. " }, {});\n",
  24102. "}\n",
  24103. "\n",
  24104. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  24105. " var canvas_pos = mpl.findpos(event)\n",
  24106. "\n",
  24107. " if (name === 'button_press')\n",
  24108. " {\n",
  24109. " this.canvas.focus();\n",
  24110. " this.canvas_div.focus();\n",
  24111. " }\n",
  24112. "\n",
  24113. " var x = canvas_pos.x * mpl.ratio;\n",
  24114. " var y = canvas_pos.y * mpl.ratio;\n",
  24115. "\n",
  24116. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  24117. " step: event.step,\n",
  24118. " guiEvent: simpleKeys(event)});\n",
  24119. "\n",
  24120. " /* This prevents the web browser from automatically changing to\n",
  24121. " * the text insertion cursor when the button is pressed. We want\n",
  24122. " * to control all of the cursor setting manually through the\n",
  24123. " * 'cursor' event from matplotlib */\n",
  24124. " event.preventDefault();\n",
  24125. " return false;\n",
  24126. "}\n",
  24127. "\n",
  24128. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  24129. " // Handle any extra behaviour associated with a key event\n",
  24130. "}\n",
  24131. "\n",
  24132. "mpl.figure.prototype.key_event = function(event, name) {\n",
  24133. "\n",
  24134. " // Prevent repeat events\n",
  24135. " if (name == 'key_press')\n",
  24136. " {\n",
  24137. " if (event.which === this._key)\n",
  24138. " return;\n",
  24139. " else\n",
  24140. " this._key = event.which;\n",
  24141. " }\n",
  24142. " if (name == 'key_release')\n",
  24143. " this._key = null;\n",
  24144. "\n",
  24145. " var value = '';\n",
  24146. " if (event.ctrlKey && event.which != 17)\n",
  24147. " value += \"ctrl+\";\n",
  24148. " if (event.altKey && event.which != 18)\n",
  24149. " value += \"alt+\";\n",
  24150. " if (event.shiftKey && event.which != 16)\n",
  24151. " value += \"shift+\";\n",
  24152. "\n",
  24153. " value += 'k';\n",
  24154. " value += event.which.toString();\n",
  24155. "\n",
  24156. " this._key_event_extra(event, name);\n",
  24157. "\n",
  24158. " this.send_message(name, {key: value,\n",
  24159. " guiEvent: simpleKeys(event)});\n",
  24160. " return false;\n",
  24161. "}\n",
  24162. "\n",
  24163. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  24164. " if (name == 'download') {\n",
  24165. " this.handle_save(this, null);\n",
  24166. " } else {\n",
  24167. " this.send_message(\"toolbar_button\", {name: name});\n",
  24168. " }\n",
  24169. "};\n",
  24170. "\n",
  24171. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  24172. " this.message.textContent = tooltip;\n",
  24173. "};\n",
  24174. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  24175. "\n",
  24176. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  24177. "\n",
  24178. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  24179. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  24180. " // object with the appropriate methods. Currently this is a non binary\n",
  24181. " // socket, so there is still some room for performance tuning.\n",
  24182. " var ws = {};\n",
  24183. "\n",
  24184. " ws.close = function() {\n",
  24185. " comm.close()\n",
  24186. " };\n",
  24187. " ws.send = function(m) {\n",
  24188. " //console.log('sending', m);\n",
  24189. " comm.send(m);\n",
  24190. " };\n",
  24191. " // Register the callback with on_msg.\n",
  24192. " comm.on_msg(function(msg) {\n",
  24193. " //console.log('receiving', msg['content']['data'], msg);\n",
  24194. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  24195. " ws.onmessage(msg['content']['data'])\n",
  24196. " });\n",
  24197. " return ws;\n",
  24198. "}\n",
  24199. "\n",
  24200. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  24201. " // This is the function which gets called when the mpl process\n",
  24202. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  24203. "\n",
  24204. " var id = msg.content.data.id;\n",
  24205. " // Get hold of the div created by the display call when the Comm\n",
  24206. " // socket was opened in Python.\n",
  24207. " var element = $(\"#\" + id);\n",
  24208. " var ws_proxy = comm_websocket_adapter(comm)\n",
  24209. "\n",
  24210. " function ondownload(figure, format) {\n",
  24211. " window.open(figure.imageObj.src);\n",
  24212. " }\n",
  24213. "\n",
  24214. " var fig = new mpl.figure(id, ws_proxy,\n",
  24215. " ondownload,\n",
  24216. " element.get(0));\n",
  24217. "\n",
  24218. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  24219. " // web socket which is closed, not our websocket->open comm proxy.\n",
  24220. " ws_proxy.onopen();\n",
  24221. "\n",
  24222. " fig.parent_element = element.get(0);\n",
  24223. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  24224. " if (!fig.cell_info) {\n",
  24225. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  24226. " return;\n",
  24227. " }\n",
  24228. "\n",
  24229. " var output_index = fig.cell_info[2]\n",
  24230. " var cell = fig.cell_info[0];\n",
  24231. "\n",
  24232. "};\n",
  24233. "\n",
  24234. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  24235. " var width = fig.canvas.width/mpl.ratio\n",
  24236. " fig.root.unbind('remove')\n",
  24237. "\n",
  24238. " // Update the output cell to use the data from the current canvas.\n",
  24239. " fig.push_to_output();\n",
  24240. " var dataURL = fig.canvas.toDataURL();\n",
  24241. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  24242. " // the notebook keyboard shortcuts fail.\n",
  24243. " IPython.keyboard_manager.enable()\n",
  24244. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  24245. " fig.close_ws(fig, msg);\n",
  24246. "}\n",
  24247. "\n",
  24248. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  24249. " fig.send_message('closing', msg);\n",
  24250. " // fig.ws.close()\n",
  24251. "}\n",
  24252. "\n",
  24253. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  24254. " // Turn the data on the canvas into data in the output cell.\n",
  24255. " var width = this.canvas.width/mpl.ratio\n",
  24256. " var dataURL = this.canvas.toDataURL();\n",
  24257. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  24258. "}\n",
  24259. "\n",
  24260. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  24261. " // Tell IPython that the notebook contents must change.\n",
  24262. " IPython.notebook.set_dirty(true);\n",
  24263. " this.send_message(\"ack\", {});\n",
  24264. " var fig = this;\n",
  24265. " // Wait a second, then push the new image to the DOM so\n",
  24266. " // that it is saved nicely (might be nice to debounce this).\n",
  24267. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  24268. "}\n",
  24269. "\n",
  24270. "mpl.figure.prototype._init_toolbar = function() {\n",
  24271. " var fig = this;\n",
  24272. "\n",
  24273. " var nav_element = $('<div/>')\n",
  24274. " nav_element.attr('style', 'width: 100%');\n",
  24275. " this.root.append(nav_element);\n",
  24276. "\n",
  24277. " // Define a callback function for later on.\n",
  24278. " function toolbar_event(event) {\n",
  24279. " return fig.toolbar_button_onclick(event['data']);\n",
  24280. " }\n",
  24281. " function toolbar_mouse_event(event) {\n",
  24282. " return fig.toolbar_button_onmouseover(event['data']);\n",
  24283. " }\n",
  24284. "\n",
  24285. " for(var toolbar_ind in mpl.toolbar_items){\n",
  24286. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  24287. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  24288. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  24289. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  24290. "\n",
  24291. " if (!name) { continue; };\n",
  24292. "\n",
  24293. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  24294. " button.click(method_name, toolbar_event);\n",
  24295. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  24296. " nav_element.append(button);\n",
  24297. " }\n",
  24298. "\n",
  24299. " // Add the status bar.\n",
  24300. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  24301. " nav_element.append(status_bar);\n",
  24302. " this.message = status_bar[0];\n",
  24303. "\n",
  24304. " // Add the close button to the window.\n",
  24305. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  24306. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  24307. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  24308. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  24309. " buttongrp.append(button);\n",
  24310. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  24311. " titlebar.prepend(buttongrp);\n",
  24312. "}\n",
  24313. "\n",
  24314. "mpl.figure.prototype._root_extra_style = function(el){\n",
  24315. " var fig = this\n",
  24316. " el.on(\"remove\", function(){\n",
  24317. "\tfig.close_ws(fig, {});\n",
  24318. " });\n",
  24319. "}\n",
  24320. "\n",
  24321. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  24322. " // this is important to make the div 'focusable\n",
  24323. " el.attr('tabindex', 0)\n",
  24324. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  24325. " // off when our div gets focus\n",
  24326. "\n",
  24327. " // location in version 3\n",
  24328. " if (IPython.notebook.keyboard_manager) {\n",
  24329. " IPython.notebook.keyboard_manager.register_events(el);\n",
  24330. " }\n",
  24331. " else {\n",
  24332. " // location in version 2\n",
  24333. " IPython.keyboard_manager.register_events(el);\n",
  24334. " }\n",
  24335. "\n",
  24336. "}\n",
  24337. "\n",
  24338. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  24339. " var manager = IPython.notebook.keyboard_manager;\n",
  24340. " if (!manager)\n",
  24341. " manager = IPython.keyboard_manager;\n",
  24342. "\n",
  24343. " // Check for shift+enter\n",
  24344. " if (event.shiftKey && event.which == 13) {\n",
  24345. " this.canvas_div.blur();\n",
  24346. " event.shiftKey = false;\n",
  24347. " // Send a \"J\" for go to next cell\n",
  24348. " event.which = 74;\n",
  24349. " event.keyCode = 74;\n",
  24350. " manager.command_mode();\n",
  24351. " manager.handle_keydown(event);\n",
  24352. " }\n",
  24353. "}\n",
  24354. "\n",
  24355. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  24356. " fig.ondownload(fig, null);\n",
  24357. "}\n",
  24358. "\n",
  24359. "\n",
  24360. "mpl.find_output_cell = function(html_output) {\n",
  24361. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  24362. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  24363. " // IPython event is triggered only after the cells have been serialised, which for\n",
  24364. " // our purposes (turning an active figure into a static one), is too late.\n",
  24365. " var cells = IPython.notebook.get_cells();\n",
  24366. " var ncells = cells.length;\n",
  24367. " for (var i=0; i<ncells; i++) {\n",
  24368. " var cell = cells[i];\n",
  24369. " if (cell.cell_type === 'code'){\n",
  24370. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  24371. " var data = cell.output_area.outputs[j];\n",
  24372. " if (data.data) {\n",
  24373. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  24374. " data = data.data;\n",
  24375. " }\n",
  24376. " if (data['text/html'] == html_output) {\n",
  24377. " return [cell, data, j];\n",
  24378. " }\n",
  24379. " }\n",
  24380. " }\n",
  24381. " }\n",
  24382. "}\n",
  24383. "\n",
  24384. "// Register the function which deals with the matplotlib target/channel.\n",
  24385. "// The kernel may be null if the page has been refreshed.\n",
  24386. "if (IPython.notebook.kernel != null) {\n",
  24387. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  24388. "}\n"
  24389. ],
  24390. "text/plain": [
  24391. "<IPython.core.display.Javascript object>"
  24392. ]
  24393. },
  24394. "metadata": {},
  24395. "output_type": "display_data"
  24396. },
  24397. {
  24398. "data": {
  24399. "text/html": [
  24400. "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA2AAAAJACAYAAADrSQUmAAAgAElEQVR4nO3de7zddX3n+zcJIkhFES8JQiCAFyynOILjAF4ikOzYwmin5XA9RFCPVUHRYq2UDgEvEEiCj2Pp1A7a0bGn55T2tA8fD3FaRyuKThGpjqAiggRysUhAM+Em0n7PH79fyGaz1iaXnctnr+fz8Xg9Sn6/tXbW/j22Td7Za62dAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABTaL8kn0qyJskvkqxI8rEke+/AxwQAADDtHJzkniQtyd8muSzJl/tf35pknx330AAAAKaXv0s3ts6dcHx5f/xPtvsjAgAAmIYOTjey7kwyY8K5ZyZ5IMmDSfbczo8LAABg2nlrugH2iSHnN3x37Ljt9ogAAACmqSvSDazfHXL+j/rz79jCj39nkvuS3CRJUtHuS/fnGQBstT9NN7DeOuT8R/rzH3yKjzPsD63HZmRme2aeLUlSyWZkZks3wgBgq23rAfbgM/Psdvwuvy1JUsmemWe3/s80ANhq2/opiDcZYJKkyhlgAEylbf0mHAaYJKl0BhgAU2lbvw29ASZJKp0BBsBU25Y/iNkAkySVzgADYKodnOSedGPrb5NcmuTL/a9/mGSfrfjYBpgkqXQGGADbwv5J/izJT5I8muSuJB9LsvdWflwDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADGB2/neTjSb6W5H8laUk++xT3OTrJtUnuT/Jwku8mOS/JzEnuc0KSryRZl+SBJDckWbQVj3s8A0ySVDoDDGB0fCfd6Fqf5Ad56gH2xiSPpRtRn0xyRZJb+/tdM+Q+5/Tn1ya5KsmVSVb2x5Zu9WdggEmSimeAAYyO1yd5UZJdkszL5ANsryQ/TfKLJEeOO757km/09z1lwn0OTPJIkvv6/95g7yS39/c5assffhIDTJJUPAMMYDTNy+QD7Oz+/KcHnDu2P3fdhOOX9Mcv3syPtzkMMElS6QwwgNE0L5MPsM/2508dcG7XJA8m+WWSp487fn2Gf5drdn9u5ZY93McZYJKk0hlgAKNpXiYfYDf2548Ycv6W/vyh447d2x/bZ8h9HujPP2MTHt9NQ3rQAJMkVc4AAxhN8zL5ALutP3/IkPNfz5O/2/Vof2zXIfdZ3Z+fvQmPzwCTJE3LDDCA0TQvO/cAG8ZTECVJpTPAAEbTvOzcT0EcxgCTJJXOAAMYTfPiTTgkSdruGWAAo2levA29JEnbPQMMYDTNy1P/IOZ7s3k/iHlu/CBmSZImzQADGB1vSvJf+v5bukF0x7hjSwfc/rF0r926OsnlSW7t73dNkl0G/B7n9ufXJrkqyZXpnnbYBnz8LWGASZJKZ4ABjI7F6YbQsFYMuM8xSa5N8rMkDye5Ocl7k8yc5Pc5Md3TE9ene63YjUkWTcHjTwwwSVLxDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwTZ9mnLTjH4Ok7Z4BBkAlBpimRzNPbvOfdko7fubJhpg0YhlgAFRigGlaNP9pp7QFe5zRjbCd4PFI2n4ZYABUYoBpWjR/t9Pa/N1O890vaQQzwACoxADT9MhTD6WRzQADoBIDTNMj40sa2QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAMYDfskeWuSv0lye5KHk6xLcn2StySZMeR+Rye5Nsn9/X2+m+S8JDMn+b1OSPKV/uM/kOSGJIu29hPoGWCSpNIZYACj4XeStCRrkvx5kkuTfCrJz/vjf5Vklwn3eWOSx9KNqE8muSLJrf3trxny+5zTn1+b5KokVyZZ2R9bOgWfhwEmSSqdAQYwGo5NcmKe/J2uWUnuTjeQfmvc8b2S/DTJL5IcOe747km+0d/+lAkf68AkjyS5r//vDfZO9123luSoLf8UkhhgkqTiGWAAXJBuHH183LGz+2OfHnD7Y/tz1004fkl//OIB95ns420OA0ySVDoDDID3pxtHV4479tn+2KkDbr9rkgeT/DLJ08cdvz7Dv8s1uz+3cisfqwEmSSqdAQYw2nZNcnO6cTQ27viN/bEjhtzvlv78oeOO3dsf22fIfR7ozz9jEx7XTUN60ACTJFXOAAMYbUvTjaLPTzh+W3/8kCH3+3qe/N2uR/tjuw65z+r+/OxNeFwGmCRpWmaAAYyud6cbRD9I8pwJ53b0ABvGUxAlSaUzwABG04a3i/9eundCnGhHPwVxGANMklQ6Awxg9JyXbgjdnOT5Q27jTTgkSdoGGWAAo+UD6YbQt5M8d5LbeRt6SZK2QQYYwOj4w3Qj6Ft58mu+Jtor3VMKN+cHMc+NH8QsSdKkGWAAo2FRugH0WLqf97V4QG+ecJ839bd/IMnVSS5Pcmv/ca5JssuA3+fc/vzaJFf1v9fK/tjSKfg8DDBJUukMMIDRsDjdCJqsrwy43zFJrk3ysyQPp3vd2HuTzJzk9zox3dMT16d7rdiN6QbgVDDAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDCA0bEkyZeSrEzycJL7k3w7yUVJ9hlyn6OTXNvf9uEk301yXpKZk/w+JyT5SpJ1SR5IckOSRVv96DsGmCSpdAYYwOh4NMk/JvlUksuSfDzJjUlaktVJ9p9w+zcmeSzdiPpkkiuS3Nrf/pohv8c5/fm1Sa5KcmW6wdeSLJ2Cz8EAkySVzgADGB27Dzn+kXQD6Y/HHdsryU+T/CLJkRM+xjf6258y4eMcmOSRJPf1/73B3klu7+9z1BY98o0MMElS6QwwAA5PN46+OO7Y2f2xTw+4/bH9uesmHL+kP37xgPtM9vE2hwEmSSqdAQbAhenG0bJxxz7bHzt1wO13TfJgkl8mefq449dn+He5ZvfnVm7lYzXAJEmlM8AARs/5SRane33W19INo/+Z5HnjbrPhtWFHDPkYt/TnDx137N7+2LA39HigP/+MTXiMNw3pQQNMklQ5Awxg9PxzuiG0oS8kecGE29zWnztkyMf4ep783a5H+2O7DrnP6v787E14jAaYJGlaZoABjK4XJPnNJD9MsibJK8ad29EDbBhPQZQklc4AA+CAdO92eMu4Yzv6KYjDGGCSpNIZYAAk3Q9kbkme2//am3BIkrQNMsAASJJ70g2kvftfext6SZK2QQYYwGh4cZJnDTg+Ixt/EPPXxx3fK91TCjfnBzHPjR/ELEnSpBlgAKPhvCQPp/thy3+a5NIkn0pyR7ph9JMkL5twnzcleSzda7euTnJ5klv721+TZJcBv8+5/fm1Sa5K91b3K/tjS6fg8zDAJEmlM8AARsNhSf4oyXfSjaPHkqxL92Ybi5M8Z8j9jklybZKfpRtwNyd5b5KZk/xeJ6Z7euL6dK8VuzHJoq39BHoGmCSpdAYYAJUYYJKk0hlgAFRigEmSSmeAAVCJASZJKp0BBkAlBpgkqXQGGACVGGCSpNIZYABUYoBJkkpngAFQiQEmSSqdAQZAJQaYJKl0BhgAlRhgkqTSGWAAVGKASZJKZ4ABUIkBJkkqnQEGQCUGmCSpdAYYAJUYYJKk0hlgAFRigEmSSmeAAVCJASZJKp0BBkAlBpgkqXQGGACVGGCSpNIZYABUYoBJkkpngAFQiQEmSSqdAQZAJQaYJKl0BhgAlRhgkqTSGWAAVGKASZJKZ4ABUIkBJkkqnQEGQCUGmCSpdAYYAJUYYJKk0hlgAFRigEmSSmeAAVCJASZJKp0BBkAlBpgkqXQGGACVGGCSpNIZYABUYoBJkkpngAFQiQEmSSqdAQZAJQaYJKl0BhgAlRhgkjatGSd17ejHIU3IAAOgEgNM0uTNOKkdP/PkNn+309r83U5rx8882RDTTpUBBkAlBpikwc04qc3f7bQ2tvdb2sK572vzj7yoHf+qi9vYi97fxp739rZgzzM3DrId/Vg10hlgAFRigEka2II9zmhjs97ZFvxvF7bX/MaSdvg7l7WXXrC8vfKMpe24Yz7UFs59Xxt7ztvagj3P9F0x7dAMMAAqMcAkPbkZJ7WFc85rrxu7rB323uVtzn+6vB1x7Qfb6f94djvi2g+2gy9d1o466Yq24N/8x7Zwv3c/8bthhpi2cwYYAJUYYJKe3MyT26tPvLzN+cTl7dT/8da27PvHt7/80SvaP9x5SPvcHYe1j97yhvbKL/x+e8mFy9urT7y8Ldzv3W1s77e0BXuc0eY/7ZRuiBlj2k4ZYABUYoBJelLzdz+9HbxkWfvQzb/R/seKA9ptd89qt989q921svu/t9y1b/uHOw9pl31vrP3a5y5sr/n1JW3sZR/snrK411ndENvtNANM2yUDDIBKDDBJT2zmyW1s77e0M284q91296x2/+oXtvWr5zypdav3a2tX7dtWrZzVPnfHYe3Er76rvfSC5e24oz/UDbE9ztjxn4tGIgMMgEoMMEkb69/5cOHsd7XLvjfWVq2c1davntMeWnNAe2jNAe2RNXMfb8Oxdav3a3etnNW+eudB7Tev/532b962rC08+PzuzTl29OejkcgAA6ASA0xS14yT2vynndIW7HVWGzvsD9oX7ji0rV217+PD69E1Bw3skTVz27rV+7WfrJrdvvTjF7eD/58PteOO+VAb2/stnoKo7ZIBBkAlBpikjT/z61lnt4UH/W478sxl7c7+u1/jx9e//OSQJ7VhhK1fPaf9ZNXs9skfHt1e9nvL28K57zPAtF0ywACoxACTRr0ZJ238mV+HX9iOePOydszfv7+tW73f4+Nr0PCaOMIeXXNQe2jNAe2ulbPa2d9c1F797y/v3hHRCNM2zgADoBIDTBrx5u9+els4933tNScsaQctWdbO/uaidtOK/Td5fE0cYutXz2k/uHt2e8lfL24LfmVR93b0O8HnqembAQZAJQaYNOItePkftgP+60fb3//4Je2eVbPbQ2sO2OzhNWiIrV21bzvmTZe3see8rftO2E7wuWp6ZoABUIkBJo14r/mNJe1dN53aVq2cNSXja0MPrTmgzfnE5W3sRe9v83c/3VMRtc0ywACoxACTRrkZJ7UjFy1rf3rrq9v9q1+4RU87nOy7YG//1hlt3nGXdk9FNMC0jTLAAKjEAJNGuRkntcPfuaz9+W2vbOtW7zdl42vDAPvMba9q//b0pd1b0nstmLZRBhgAlRhg0ig38+T2st9b3v7yR6+Y8gH2Lz85pP317S9vR565zADTNs0AA6ASA0wa4ebvdlo76Ipl7XN3HLZNBtjHvn9ce82vL/EURG3TDDAAKjHApBFt/tNOaQv3f0876Rv/Z/v2Xfs9/nO/pvIpiHP/74+0hXPO8y6I2qYZYABUYoBJo9iMk9qCPc9s84+8qF3xvQXttrtnbdYPXt7UAXbIh5e1see93dMPtU0zwACoxACTRrGZJ7ex57+jHf1bV7TP3XFYu3PlrHb/6he29avntIfWHDAl3wl7ZM3cdvg7vP5L2z4DDIBKDDBpBJu/22lt7MW/1371/OXtmyvmtFUrZ7V7Vs1+vLWr9t2q74Y9uuagtm71fu3fnby0jT3rbANM2zQDDIBKDDBpBFuwxxlt/isuanOXL2233LVvW7VyVrtr5az2g7tnt6/eeVD70o9f3O5ZNXuLfzDzo2sOavesmt2OedPlBpi2eQYYAJUYYNKo1b/+6/hXXdzm/Ocl7aYV+7ebVuzf/uyH/6698gu/317yH5e3w9+xrJ38jbe1797VPS1xU0fYo2sOao+smdvWr57T7lw5q7387cvawtnv8iYc2qYZYABUYoBJo9aMk57wHbC/vv3lbdn3j2+/9rkL26+9a3k77tUfbgsOv7Ad8pFl7bLvjbVVK2cN/U7Yo2sOenx0PbJmbntozQFt/eo5be2qfdttd89qh3x4WVt48Plt/u6next6bbMMMAAqMcCkEWz+7qe3sZf+fvvV85e3+f/wnjbnk5e1I85a1ua/4qK2cL93t7Hnv6O9bv6l7eD/95L2pR+/uK1dte/jb84xfmitW71fu2fV7HbnylmPd9fKWe32u2e1b9+1X5tz9ZI2/8iLuu+4GWDaRhlgAFRigEkj2PynndIW7ntOe+0blrTD37GsvfYNS9rYr17QFs5+Vxvb+y1twV5ntbEXvb/92jnL27tuOrXdcte+be2qfdv9q1/Y7lk1u63qXy/2D3ce0v7Tra9tb//WGe0D3/kP7f/6wevbX/7oFe0LdxzaPnfHYe2Az3y0HTvvI34Qs7ZpBhgAlRhg0ijWvw5s4f7vaQsPPr8t3PecNvact7UFe53VFux5Zluw55ltbNY727zjLm1z/+LD7c9ve2X7wd2z2+13z2rfveuF7e9//JL2se8f195w3bltztVL2qEfXN4OvmxZO+C/frS95ovntzNvOKu966ZT28FLlrX5R17UPQVxR3/OmrYZYABUYoBJo9qMk9r83U5r83c/fWBjz3lbGzvsD9qhH1ze3nzDm9vn7/jV9tU7D2p/8aMj2nn/9L+3l/5/F7WXXrC8vfrfX96Of9XFbd7xl7ZX/h9L20svWN4OvHJpO+CqK7p3QZz1Tu+CqG2aAQZAJQaYpCc246TH36hj7Hlvb/P/7cXtJRcub8d/+bz2ge/8h3bU3/1eO+TDy9prfn1JG3vJB9rYrHd2Y+15b29js97ZPY3x+e/ofgCzpx1qO2SAAVCJASZpcDNP7p6mOPd97ajfvqLN+cTl7Te+ek474DMfbS9/+7I2/5WLuzfs2PstbcEeZ3TvrLj76d1bzs882fjSdssAA6ASA0zS8Gae3Bb8yqI29pIPtCPPXNbm/Ocl7aV/sLy99g1L2sKDfvfx8fX44DK6tAMywACoxACTNHn90xEXzjmvHfOmy9uxr/lwW3jge9uCX1nUfbfL6NIOzgADoBIDTNKmNfPkNvassw0v7XQZYABUYoBJkkpngAFQiQEmSSqdAQZAJQaYJKl0BhgAlRhgkqTSGWAAo+2MJK3vrUNuc0KSryRZl+SBJDckWfQUH3dRkm/2t1/X3/+ErX60BpgkqXgGGMDo2j/Jz5Osz/ABdk5/bm2Sq5JcmWRlf2zpkI+7tD+/sr/9VUnu64+ds5WP2QCTJJXOAAMYTbsk+e9J7khyRQYPsAOTPJJuPB047vjeSW7v73PUhPsc3R+/vb/d+I91X//xDsyWM8AkSaUzwABG03uS/GuS1yZZnMED7JL++MUD7n92f+7TE45/pj9+1oD7TPbxNpUBJkkqnQEGMHoOTfJwuqcHJsMH2PUZ/F2uJJmdjU8zHG9Vf3z2gPsc1Z/72pY86J4BJkkqnQEGMFp2TfKtJD9Mskd/bHEGD7B7++P7DPlYD/Tnn9H/es/+1+uH3P65/fl7NuFx3jSkBw0wSVLlDDCA0XJJkn/JE7+rtTiDB9ij/fFdh3ys1Xnid7v27X+9asjtn9af/8UmPE4DTJI0LTPAAEbHq5I8luTyCccXZ+cbYMN4CqIkqXQGGMBo2DXd0w6/n+TpE84tzs73FMRhDDBJUukMMIDR8Oxs/IHLT9XH+vt4Ew5JkqY4AwxgNOyR5Ooh/VM2DqOrk5zc38fb0EuSNMUZYAAszuCnIM6NH8QsSdKUZoABsDiDB1iSnNufW5vkqnQ/O2xlf2zpkI+3LBufnnhlf7+1/bFztvKxGmCSpNIZYAAszvABliQnJrku3ZtrPJjkxiSLnuJjvrm/3YP9/a5LcsLWP1QDTJJUOwMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMJwFnkMAAAs7SURBVElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADGB0rkrQh/fOQ+xyd5Nok9yd5OMl3k5yXZOYkv88JSb6SZF2SB5LckGTR1j74ngEmSSqdAQYwOlYk+XmSxQM6f8Dt35jksXQj6pNJrkhya7rBds2Q3+Oc/vzaJFcluTLJyv7Y0q3+DAwwSVLxDDCA0bGib1PsleSnSX6R5Mhxx3dP8o10g+qUCfc5MMkjSe7r/3uDvZPc3t/nqM16xE9mgEmSSmeAAYyOFdn0AXZ2usH06QHnju3PXTfh+CX98Ys38+NtDgNMklQ6AwxgdKxI8pMkZyS5IMl7krw+g1/P9dl0g+nUAed2TfJgkl8mefq449dn+He5ZvfnVm7ZQ3+cASZJKp0BBjA6VmTwG3D8OMnrJtz2xv7cEUM+1i39+UPHHbu3P7bPkPs80J9/xiY81puG9KABJkmqnAEGMDouSvf0wRekG0GHJfmTJP+a5KEkh4+77W3pxtIhQz7W1/Pk73Y92h/bdch9VvfnZ2/CYzXAJEnTMgMMgKXphtHfjDu2owfYMJ6CKEkqnQEGwCHphtF9447t6KcgDmOASZJKZ4AB8Kx0w+iRcce8CYckSdsgAwyAsXTj6PvjjnkbekmStkEGGMBoODTJngOOH5jkR+nG0QXjju+V7imFm/ODmOfGD2KWJGnSDDCA0bA4yfokn0/yx0mWJPmrJA+nG0afT7LbhPu8Kclj6V67dXWSy5Pc2t/+miS7DPh9zu3Pr01yVZIr0z3tsKV7s4+tZYBJkkpngAGMhtcl+Yt0A+rn6V6/dW+SLyY5M4PHVJIck+TaJD9LN9ZuTvLeDP7hzRucmO7pievTvVbsxiSLtvoz6BhgkqTSGWAAVGKASZJKZ4ABUMl9MzKzPTPPliSpZDMyc+KPfgGAndad6V6X9mC6fz3U1PSga+qaFsg1dU139jb1et6X7s8zAChhwx9gTB3XdOq5plPPNZ16runUcj0BmJb8ATf1XNOp55pOPdd06rmmU8v1BGBa8gfc1HNNp55rOvVc06nnmk4t1xOAackfcFPPNZ16runUc02nnms6tVxPAKYlf8BNPdd06rmmU881nXqu6dRyPQGYlvwBN/Vc06nnmk4913TquaZTy/UEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGHH7JflUkjVJfpFkRZKPJdl7Bz6mncVvJ/l4kq8l+V9JWpLPPsV9jk5ybZL7kzyc5LtJzksyc5L7nJDkK0nWJXkgyQ1JFm3F495Z7ZPkrUn+Jsnt6a7PuiTXJ3lLkhlD7ueaTm5Jki8lWZnu+tyf5NtJLkp3zQdxTTfPGen+99/SfQ0PsiXXZ1GSb/a3X9ff/4StfrQ7pxXZeA0n9s9D7uPrFIBp5+Ak96T7A/Bvk1yW5Mv9r2/N8L+8jYrvpLsW65P8IE89wN6Y5LF0f+h/MskV6a5jS3LNkPuc059fm+SqJFem+4t0S7J0qz+DncvvpPu81iT58ySXphv/P++P/1WSXSbcxzV9ao8m+cd01/KydP9ocGO6z3d1kv0n3N413Tz7p/saXZ/hA2xLrs/S/vzK/vZXJbmvP3bO1D38ncaKdNdx8YDOH3B7X6cATEt/l+4PpnMnHF/eH/+T7f6Idi6vT/KidKNgXiYfYHsl+Wm67yIeOe747km+0d/3lAn3OTDJI+n+0nXguON7p/sOUUty1JY//J3OsUlOzJO/0zUryd3pPt/fGnfcNd00uw85/pF0n+8fjzvmmm6eXZL89yR3pBsAgwbYgdn863N0f/z2PPHZBgf2H+eRCR9rOljRtyl8nQIwLR2c7g+kO/PkvxA/M92/Oj6YZM/t/Lh2VvMy+QA7uz//6QHnju3PXTfh+CX98Ys38+NNRxek+3w/Pu6Ya7p1Dk/3+X5x3DHXdPO8J8m/Jnltuu/UDBpgW3J9PtMfP2vAfSb7eJWtyKYPMF+nAExLb033B9Inhpzf8N2x47bbI9q5zcvkA+yz/flTB5zbNd2Y/WWSp487fn2G/6vs7Gx8etIoeH+6z/fKccdc061zYbrPd9m4Y67ppjs03euONnxNLs7gAbYl12dVf3z2gPsc1Z/72pY86J3YiiQ/Sfd6ugvSjdvXZ/DruXydAjAtbXg6ze8OOf9H/fl3bLdHtHObl8kH2IbX3Bwx5Pwt/flDxx27tz827LV2D/Tnn7GZj7WaXZPcnO5zHRt33DXdPOenGwlXpvvLe0vyP5M8b9xtXNNNs2uSbyX5YZI9+mOLM3iAbe712TMbX1s6yHP78/dswePema3I4Dfg+HGS1024ra9TAKalP83k7+i14fUjH9xuj2jnNi+TD7Db+vOHDDn/9Tz5X2cf7Y/tOuQ+qzP8X8mnkw1vRvD5Ccdd083zz3niX2y/kOQFE27jmm6aS5L8S554HRZn8P/P3Nzrs2//61VDbv+0/vwvNvdB7+QuSvf0wRekG0GHpXud8b8meSjdU2Y38HUKwLRkgG2eeTHAtoV3p/scf5DkORPOuaZb5gVJfjPdd2/WJHnFuHOu6VN7Vbp337t8wvHFMcC2hQ3/APM34475OgVgWvIUxM0zL56CONU2vGX099K9E+JErunWOSDdX+JvGXfMNZ3crumG6/fzxNcXJZ6CuK0cku7zvW/cMV+nAExL3oRj88zL5APMi8Y3z3npPr+bkzx/yG1c06337XSf83P7X7umk3t2Br9OaVAf6+/jTTi2zrPSfb6PjDvm6xSAacnb0G+eeZl8gHnb5E33gXSf27ezcRgM4ppuvQ0/aH3Dz5pyTSe3R5Krh/RP2TiMrk5ycn8fb0O/dcbSfb7fH3fM1ykA05YfxLzp5mXyAbZXuqfAbM4PDp2b0fvBoX+Y7vP6Vp78mq+JXNOn9uJ030GYaEY2vo7z6+OOu6ZbbnEGPwVxS67PqP0g5kMz+B/zDkzyo3TX4oJxx32dAjBtHZyN/0L+t0kuTfLl/tc/zPDn0o+KNyX5L33/Ld11uWPcsaUDbv9Yuu8eXp3uRfy39ve7JskuA36Pc/vza5Ncle4txFf2xyZ+/OoWpfu8Hkv3eS4e0Jsn3Mc1ndx56X5W1RfTvbHOpUk+le7rtKX7uUsvm3Af13TLLM7gAZZs2fVZlo1Pi7uyv9/a/tg5U/i4dwaL073m7fNJ/jjJkiR/le5rt/XHd5twH1+nAExb+yf5s3R/UXs0yV3pXtuw92R3GhGLM/lrQFYMuM8xSa5N8rN0f7m4Ocl7M/iHjW5wYrqn06xP97TPG9ONlelmcZ76dTVfGXA/13S4w9K9Yc530v2l87Ek69J9vosz/LuMrunmW5zhAyzZsuvz5v52D/b3uy7JCVv/UHc6r0vyF+kG1M/TvX7r3nT/cHBmBo+pxNcpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7Cz+f9jAxVZbUOUUAAAAAElFTkSuQmCC\" width=\"432\">"
  24401. ],
  24402. "text/plain": [
  24403. "<IPython.core.display.HTML object>"
  24404. ]
  24405. },
  24406. "metadata": {},
  24407. "output_type": "display_data"
  24408. },
  24409. {
  24410. "name": "stdout",
  24411. "output_type": "stream",
  24412. "text": [
  24413. "-0.22168608 4.574376\n",
  24414. "19171.67\n",
  24415. "(244, 203)\n",
  24416. "\n"
  24417. ]
  24418. },
  24419. {
  24420. "data": {
  24421. "application/javascript": [
  24422. "/* Put everything inside the global mpl namespace */\n",
  24423. "window.mpl = {};\n",
  24424. "\n",
  24425. "\n",
  24426. "mpl.get_websocket_type = function() {\n",
  24427. " if (typeof(WebSocket) !== 'undefined') {\n",
  24428. " return WebSocket;\n",
  24429. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  24430. " return MozWebSocket;\n",
  24431. " } else {\n",
  24432. " alert('Your browser does not have WebSocket support.' +\n",
  24433. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  24434. " 'Firefox 4 and 5 are also supported but you ' +\n",
  24435. " 'have to enable WebSockets in about:config.');\n",
  24436. " };\n",
  24437. "}\n",
  24438. "\n",
  24439. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  24440. " this.id = figure_id;\n",
  24441. "\n",
  24442. " this.ws = websocket;\n",
  24443. "\n",
  24444. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  24445. "\n",
  24446. " if (!this.supports_binary) {\n",
  24447. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  24448. " if (warnings) {\n",
  24449. " warnings.style.display = 'block';\n",
  24450. " warnings.textContent = (\n",
  24451. " \"This browser does not support binary websocket messages. \" +\n",
  24452. " \"Performance may be slow.\");\n",
  24453. " }\n",
  24454. " }\n",
  24455. "\n",
  24456. " this.imageObj = new Image();\n",
  24457. "\n",
  24458. " this.context = undefined;\n",
  24459. " this.message = undefined;\n",
  24460. " this.canvas = undefined;\n",
  24461. " this.rubberband_canvas = undefined;\n",
  24462. " this.rubberband_context = undefined;\n",
  24463. " this.format_dropdown = undefined;\n",
  24464. "\n",
  24465. " this.image_mode = 'full';\n",
  24466. "\n",
  24467. " this.root = $('<div/>');\n",
  24468. " this._root_extra_style(this.root)\n",
  24469. " this.root.attr('style', 'display: inline-block');\n",
  24470. "\n",
  24471. " $(parent_element).append(this.root);\n",
  24472. "\n",
  24473. " this._init_header(this);\n",
  24474. " this._init_canvas(this);\n",
  24475. " this._init_toolbar(this);\n",
  24476. "\n",
  24477. " var fig = this;\n",
  24478. "\n",
  24479. " this.waiting = false;\n",
  24480. "\n",
  24481. " this.ws.onopen = function () {\n",
  24482. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  24483. " fig.send_message(\"send_image_mode\", {});\n",
  24484. " if (mpl.ratio != 1) {\n",
  24485. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  24486. " }\n",
  24487. " fig.send_message(\"refresh\", {});\n",
  24488. " }\n",
  24489. "\n",
  24490. " this.imageObj.onload = function() {\n",
  24491. " if (fig.image_mode == 'full') {\n",
  24492. " // Full images could contain transparency (where diff images\n",
  24493. " // almost always do), so we need to clear the canvas so that\n",
  24494. " // there is no ghosting.\n",
  24495. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  24496. " }\n",
  24497. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  24498. " };\n",
  24499. "\n",
  24500. " this.imageObj.onunload = function() {\n",
  24501. " fig.ws.close();\n",
  24502. " }\n",
  24503. "\n",
  24504. " this.ws.onmessage = this._make_on_message_function(this);\n",
  24505. "\n",
  24506. " this.ondownload = ondownload;\n",
  24507. "}\n",
  24508. "\n",
  24509. "mpl.figure.prototype._init_header = function() {\n",
  24510. " var titlebar = $(\n",
  24511. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  24512. " 'ui-helper-clearfix\"/>');\n",
  24513. " var titletext = $(\n",
  24514. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  24515. " 'text-align: center; padding: 3px;\"/>');\n",
  24516. " titlebar.append(titletext)\n",
  24517. " this.root.append(titlebar);\n",
  24518. " this.header = titletext[0];\n",
  24519. "}\n",
  24520. "\n",
  24521. "\n",
  24522. "\n",
  24523. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  24524. "\n",
  24525. "}\n",
  24526. "\n",
  24527. "\n",
  24528. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  24529. "\n",
  24530. "}\n",
  24531. "\n",
  24532. "mpl.figure.prototype._init_canvas = function() {\n",
  24533. " var fig = this;\n",
  24534. "\n",
  24535. " var canvas_div = $('<div/>');\n",
  24536. "\n",
  24537. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  24538. "\n",
  24539. " function canvas_keyboard_event(event) {\n",
  24540. " return fig.key_event(event, event['data']);\n",
  24541. " }\n",
  24542. "\n",
  24543. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  24544. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  24545. " this.canvas_div = canvas_div\n",
  24546. " this._canvas_extra_style(canvas_div)\n",
  24547. " this.root.append(canvas_div);\n",
  24548. "\n",
  24549. " var canvas = $('<canvas/>');\n",
  24550. " canvas.addClass('mpl-canvas');\n",
  24551. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  24552. "\n",
  24553. " this.canvas = canvas[0];\n",
  24554. " this.context = canvas[0].getContext(\"2d\");\n",
  24555. "\n",
  24556. " var backingStore = this.context.backingStorePixelRatio ||\n",
  24557. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  24558. "\tthis.context.mozBackingStorePixelRatio ||\n",
  24559. "\tthis.context.msBackingStorePixelRatio ||\n",
  24560. "\tthis.context.oBackingStorePixelRatio ||\n",
  24561. "\tthis.context.backingStorePixelRatio || 1;\n",
  24562. "\n",
  24563. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  24564. "\n",
  24565. " var rubberband = $('<canvas/>');\n",
  24566. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  24567. "\n",
  24568. " var pass_mouse_events = true;\n",
  24569. "\n",
  24570. " canvas_div.resizable({\n",
  24571. " start: function(event, ui) {\n",
  24572. " pass_mouse_events = false;\n",
  24573. " },\n",
  24574. " resize: function(event, ui) {\n",
  24575. " fig.request_resize(ui.size.width, ui.size.height);\n",
  24576. " },\n",
  24577. " stop: function(event, ui) {\n",
  24578. " pass_mouse_events = true;\n",
  24579. " fig.request_resize(ui.size.width, ui.size.height);\n",
  24580. " },\n",
  24581. " });\n",
  24582. "\n",
  24583. " function mouse_event_fn(event) {\n",
  24584. " if (pass_mouse_events)\n",
  24585. " return fig.mouse_event(event, event['data']);\n",
  24586. " }\n",
  24587. "\n",
  24588. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  24589. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  24590. " // Throttle sequential mouse events to 1 every 20ms.\n",
  24591. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  24592. "\n",
  24593. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  24594. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  24595. "\n",
  24596. " canvas_div.on(\"wheel\", function (event) {\n",
  24597. " event = event.originalEvent;\n",
  24598. " event['data'] = 'scroll'\n",
  24599. " if (event.deltaY < 0) {\n",
  24600. " event.step = 1;\n",
  24601. " } else {\n",
  24602. " event.step = -1;\n",
  24603. " }\n",
  24604. " mouse_event_fn(event);\n",
  24605. " });\n",
  24606. "\n",
  24607. " canvas_div.append(canvas);\n",
  24608. " canvas_div.append(rubberband);\n",
  24609. "\n",
  24610. " this.rubberband = rubberband;\n",
  24611. " this.rubberband_canvas = rubberband[0];\n",
  24612. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  24613. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  24614. "\n",
  24615. " this._resize_canvas = function(width, height) {\n",
  24616. " // Keep the size of the canvas, canvas container, and rubber band\n",
  24617. " // canvas in synch.\n",
  24618. " canvas_div.css('width', width)\n",
  24619. " canvas_div.css('height', height)\n",
  24620. "\n",
  24621. " canvas.attr('width', width * mpl.ratio);\n",
  24622. " canvas.attr('height', height * mpl.ratio);\n",
  24623. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  24624. "\n",
  24625. " rubberband.attr('width', width);\n",
  24626. " rubberband.attr('height', height);\n",
  24627. " }\n",
  24628. "\n",
  24629. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  24630. " // upon first draw.\n",
  24631. " this._resize_canvas(600, 600);\n",
  24632. "\n",
  24633. " // Disable right mouse context menu.\n",
  24634. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  24635. " return false;\n",
  24636. " });\n",
  24637. "\n",
  24638. " function set_focus () {\n",
  24639. " canvas.focus();\n",
  24640. " canvas_div.focus();\n",
  24641. " }\n",
  24642. "\n",
  24643. " window.setTimeout(set_focus, 100);\n",
  24644. "}\n",
  24645. "\n",
  24646. "mpl.figure.prototype._init_toolbar = function() {\n",
  24647. " var fig = this;\n",
  24648. "\n",
  24649. " var nav_element = $('<div/>')\n",
  24650. " nav_element.attr('style', 'width: 100%');\n",
  24651. " this.root.append(nav_element);\n",
  24652. "\n",
  24653. " // Define a callback function for later on.\n",
  24654. " function toolbar_event(event) {\n",
  24655. " return fig.toolbar_button_onclick(event['data']);\n",
  24656. " }\n",
  24657. " function toolbar_mouse_event(event) {\n",
  24658. " return fig.toolbar_button_onmouseover(event['data']);\n",
  24659. " }\n",
  24660. "\n",
  24661. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  24662. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  24663. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  24664. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  24665. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  24666. "\n",
  24667. " if (!name) {\n",
  24668. " // put a spacer in here.\n",
  24669. " continue;\n",
  24670. " }\n",
  24671. " var button = $('<button/>');\n",
  24672. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  24673. " 'ui-button-icon-only');\n",
  24674. " button.attr('role', 'button');\n",
  24675. " button.attr('aria-disabled', 'false');\n",
  24676. " button.click(method_name, toolbar_event);\n",
  24677. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  24678. "\n",
  24679. " var icon_img = $('<span/>');\n",
  24680. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  24681. " icon_img.addClass(image);\n",
  24682. " icon_img.addClass('ui-corner-all');\n",
  24683. "\n",
  24684. " var tooltip_span = $('<span/>');\n",
  24685. " tooltip_span.addClass('ui-button-text');\n",
  24686. " tooltip_span.html(tooltip);\n",
  24687. "\n",
  24688. " button.append(icon_img);\n",
  24689. " button.append(tooltip_span);\n",
  24690. "\n",
  24691. " nav_element.append(button);\n",
  24692. " }\n",
  24693. "\n",
  24694. " var fmt_picker_span = $('<span/>');\n",
  24695. "\n",
  24696. " var fmt_picker = $('<select/>');\n",
  24697. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  24698. " fmt_picker_span.append(fmt_picker);\n",
  24699. " nav_element.append(fmt_picker_span);\n",
  24700. " this.format_dropdown = fmt_picker[0];\n",
  24701. "\n",
  24702. " for (var ind in mpl.extensions) {\n",
  24703. " var fmt = mpl.extensions[ind];\n",
  24704. " var option = $(\n",
  24705. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  24706. " fmt_picker.append(option)\n",
  24707. " }\n",
  24708. "\n",
  24709. " // Add hover states to the ui-buttons\n",
  24710. " $( \".ui-button\" ).hover(\n",
  24711. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  24712. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  24713. " );\n",
  24714. "\n",
  24715. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  24716. " nav_element.append(status_bar);\n",
  24717. " this.message = status_bar[0];\n",
  24718. "}\n",
  24719. "\n",
  24720. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  24721. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  24722. " // which will in turn request a refresh of the image.\n",
  24723. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  24724. "}\n",
  24725. "\n",
  24726. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  24727. " properties['type'] = type;\n",
  24728. " properties['figure_id'] = this.id;\n",
  24729. " this.ws.send(JSON.stringify(properties));\n",
  24730. "}\n",
  24731. "\n",
  24732. "mpl.figure.prototype.send_draw_message = function() {\n",
  24733. " if (!this.waiting) {\n",
  24734. " this.waiting = true;\n",
  24735. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  24736. " }\n",
  24737. "}\n",
  24738. "\n",
  24739. "\n",
  24740. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  24741. " var format_dropdown = fig.format_dropdown;\n",
  24742. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  24743. " fig.ondownload(fig, format);\n",
  24744. "}\n",
  24745. "\n",
  24746. "\n",
  24747. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  24748. " var size = msg['size'];\n",
  24749. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  24750. " fig._resize_canvas(size[0], size[1]);\n",
  24751. " fig.send_message(\"refresh\", {});\n",
  24752. " };\n",
  24753. "}\n",
  24754. "\n",
  24755. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  24756. " var x0 = msg['x0'] / mpl.ratio;\n",
  24757. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  24758. " var x1 = msg['x1'] / mpl.ratio;\n",
  24759. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  24760. " x0 = Math.floor(x0) + 0.5;\n",
  24761. " y0 = Math.floor(y0) + 0.5;\n",
  24762. " x1 = Math.floor(x1) + 0.5;\n",
  24763. " y1 = Math.floor(y1) + 0.5;\n",
  24764. " var min_x = Math.min(x0, x1);\n",
  24765. " var min_y = Math.min(y0, y1);\n",
  24766. " var width = Math.abs(x1 - x0);\n",
  24767. " var height = Math.abs(y1 - y0);\n",
  24768. "\n",
  24769. " fig.rubberband_context.clearRect(\n",
  24770. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  24771. "\n",
  24772. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  24773. "}\n",
  24774. "\n",
  24775. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  24776. " // Updates the figure title.\n",
  24777. " fig.header.textContent = msg['label'];\n",
  24778. "}\n",
  24779. "\n",
  24780. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  24781. " var cursor = msg['cursor'];\n",
  24782. " switch(cursor)\n",
  24783. " {\n",
  24784. " case 0:\n",
  24785. " cursor = 'pointer';\n",
  24786. " break;\n",
  24787. " case 1:\n",
  24788. " cursor = 'default';\n",
  24789. " break;\n",
  24790. " case 2:\n",
  24791. " cursor = 'crosshair';\n",
  24792. " break;\n",
  24793. " case 3:\n",
  24794. " cursor = 'move';\n",
  24795. " break;\n",
  24796. " }\n",
  24797. " fig.rubberband_canvas.style.cursor = cursor;\n",
  24798. "}\n",
  24799. "\n",
  24800. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  24801. " fig.message.textContent = msg['message'];\n",
  24802. "}\n",
  24803. "\n",
  24804. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  24805. " // Request the server to send over a new figure.\n",
  24806. " fig.send_draw_message();\n",
  24807. "}\n",
  24808. "\n",
  24809. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  24810. " fig.image_mode = msg['mode'];\n",
  24811. "}\n",
  24812. "\n",
  24813. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  24814. " // Called whenever the canvas gets updated.\n",
  24815. " this.send_message(\"ack\", {});\n",
  24816. "}\n",
  24817. "\n",
  24818. "// A function to construct a web socket function for onmessage handling.\n",
  24819. "// Called in the figure constructor.\n",
  24820. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  24821. " return function socket_on_message(evt) {\n",
  24822. " if (evt.data instanceof Blob) {\n",
  24823. " /* FIXME: We get \"Resource interpreted as Image but\n",
  24824. " * transferred with MIME type text/plain:\" errors on\n",
  24825. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  24826. " * to be part of the websocket stream */\n",
  24827. " evt.data.type = \"image/png\";\n",
  24828. "\n",
  24829. " /* Free the memory for the previous frames */\n",
  24830. " if (fig.imageObj.src) {\n",
  24831. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  24832. " fig.imageObj.src);\n",
  24833. " }\n",
  24834. "\n",
  24835. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  24836. " evt.data);\n",
  24837. " fig.updated_canvas_event();\n",
  24838. " fig.waiting = false;\n",
  24839. " return;\n",
  24840. " }\n",
  24841. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  24842. " fig.imageObj.src = evt.data;\n",
  24843. " fig.updated_canvas_event();\n",
  24844. " fig.waiting = false;\n",
  24845. " return;\n",
  24846. " }\n",
  24847. "\n",
  24848. " var msg = JSON.parse(evt.data);\n",
  24849. " var msg_type = msg['type'];\n",
  24850. "\n",
  24851. " // Call the \"handle_{type}\" callback, which takes\n",
  24852. " // the figure and JSON message as its only arguments.\n",
  24853. " try {\n",
  24854. " var callback = fig[\"handle_\" + msg_type];\n",
  24855. " } catch (e) {\n",
  24856. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  24857. " return;\n",
  24858. " }\n",
  24859. "\n",
  24860. " if (callback) {\n",
  24861. " try {\n",
  24862. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  24863. " callback(fig, msg);\n",
  24864. " } catch (e) {\n",
  24865. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  24866. " }\n",
  24867. " }\n",
  24868. " };\n",
  24869. "}\n",
  24870. "\n",
  24871. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  24872. "mpl.findpos = function(e) {\n",
  24873. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  24874. " var targ;\n",
  24875. " if (!e)\n",
  24876. " e = window.event;\n",
  24877. " if (e.target)\n",
  24878. " targ = e.target;\n",
  24879. " else if (e.srcElement)\n",
  24880. " targ = e.srcElement;\n",
  24881. " if (targ.nodeType == 3) // defeat Safari bug\n",
  24882. " targ = targ.parentNode;\n",
  24883. "\n",
  24884. " // jQuery normalizes the pageX and pageY\n",
  24885. " // pageX,Y are the mouse positions relative to the document\n",
  24886. " // offset() returns the position of the element relative to the document\n",
  24887. " var x = e.pageX - $(targ).offset().left;\n",
  24888. " var y = e.pageY - $(targ).offset().top;\n",
  24889. "\n",
  24890. " return {\"x\": x, \"y\": y};\n",
  24891. "};\n",
  24892. "\n",
  24893. "/*\n",
  24894. " * return a copy of an object with only non-object keys\n",
  24895. " * we need this to avoid circular references\n",
  24896. " * http://stackoverflow.com/a/24161582/3208463\n",
  24897. " */\n",
  24898. "function simpleKeys (original) {\n",
  24899. " return Object.keys(original).reduce(function (obj, key) {\n",
  24900. " if (typeof original[key] !== 'object')\n",
  24901. " obj[key] = original[key]\n",
  24902. " return obj;\n",
  24903. " }, {});\n",
  24904. "}\n",
  24905. "\n",
  24906. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  24907. " var canvas_pos = mpl.findpos(event)\n",
  24908. "\n",
  24909. " if (name === 'button_press')\n",
  24910. " {\n",
  24911. " this.canvas.focus();\n",
  24912. " this.canvas_div.focus();\n",
  24913. " }\n",
  24914. "\n",
  24915. " var x = canvas_pos.x * mpl.ratio;\n",
  24916. " var y = canvas_pos.y * mpl.ratio;\n",
  24917. "\n",
  24918. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  24919. " step: event.step,\n",
  24920. " guiEvent: simpleKeys(event)});\n",
  24921. "\n",
  24922. " /* This prevents the web browser from automatically changing to\n",
  24923. " * the text insertion cursor when the button is pressed. We want\n",
  24924. " * to control all of the cursor setting manually through the\n",
  24925. " * 'cursor' event from matplotlib */\n",
  24926. " event.preventDefault();\n",
  24927. " return false;\n",
  24928. "}\n",
  24929. "\n",
  24930. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  24931. " // Handle any extra behaviour associated with a key event\n",
  24932. "}\n",
  24933. "\n",
  24934. "mpl.figure.prototype.key_event = function(event, name) {\n",
  24935. "\n",
  24936. " // Prevent repeat events\n",
  24937. " if (name == 'key_press')\n",
  24938. " {\n",
  24939. " if (event.which === this._key)\n",
  24940. " return;\n",
  24941. " else\n",
  24942. " this._key = event.which;\n",
  24943. " }\n",
  24944. " if (name == 'key_release')\n",
  24945. " this._key = null;\n",
  24946. "\n",
  24947. " var value = '';\n",
  24948. " if (event.ctrlKey && event.which != 17)\n",
  24949. " value += \"ctrl+\";\n",
  24950. " if (event.altKey && event.which != 18)\n",
  24951. " value += \"alt+\";\n",
  24952. " if (event.shiftKey && event.which != 16)\n",
  24953. " value += \"shift+\";\n",
  24954. "\n",
  24955. " value += 'k';\n",
  24956. " value += event.which.toString();\n",
  24957. "\n",
  24958. " this._key_event_extra(event, name);\n",
  24959. "\n",
  24960. " this.send_message(name, {key: value,\n",
  24961. " guiEvent: simpleKeys(event)});\n",
  24962. " return false;\n",
  24963. "}\n",
  24964. "\n",
  24965. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  24966. " if (name == 'download') {\n",
  24967. " this.handle_save(this, null);\n",
  24968. " } else {\n",
  24969. " this.send_message(\"toolbar_button\", {name: name});\n",
  24970. " }\n",
  24971. "};\n",
  24972. "\n",
  24973. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  24974. " this.message.textContent = tooltip;\n",
  24975. "};\n",
  24976. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  24977. "\n",
  24978. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  24979. "\n",
  24980. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  24981. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  24982. " // object with the appropriate methods. Currently this is a non binary\n",
  24983. " // socket, so there is still some room for performance tuning.\n",
  24984. " var ws = {};\n",
  24985. "\n",
  24986. " ws.close = function() {\n",
  24987. " comm.close()\n",
  24988. " };\n",
  24989. " ws.send = function(m) {\n",
  24990. " //console.log('sending', m);\n",
  24991. " comm.send(m);\n",
  24992. " };\n",
  24993. " // Register the callback with on_msg.\n",
  24994. " comm.on_msg(function(msg) {\n",
  24995. " //console.log('receiving', msg['content']['data'], msg);\n",
  24996. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  24997. " ws.onmessage(msg['content']['data'])\n",
  24998. " });\n",
  24999. " return ws;\n",
  25000. "}\n",
  25001. "\n",
  25002. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  25003. " // This is the function which gets called when the mpl process\n",
  25004. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  25005. "\n",
  25006. " var id = msg.content.data.id;\n",
  25007. " // Get hold of the div created by the display call when the Comm\n",
  25008. " // socket was opened in Python.\n",
  25009. " var element = $(\"#\" + id);\n",
  25010. " var ws_proxy = comm_websocket_adapter(comm)\n",
  25011. "\n",
  25012. " function ondownload(figure, format) {\n",
  25013. " window.open(figure.imageObj.src);\n",
  25014. " }\n",
  25015. "\n",
  25016. " var fig = new mpl.figure(id, ws_proxy,\n",
  25017. " ondownload,\n",
  25018. " element.get(0));\n",
  25019. "\n",
  25020. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  25021. " // web socket which is closed, not our websocket->open comm proxy.\n",
  25022. " ws_proxy.onopen();\n",
  25023. "\n",
  25024. " fig.parent_element = element.get(0);\n",
  25025. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  25026. " if (!fig.cell_info) {\n",
  25027. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  25028. " return;\n",
  25029. " }\n",
  25030. "\n",
  25031. " var output_index = fig.cell_info[2]\n",
  25032. " var cell = fig.cell_info[0];\n",
  25033. "\n",
  25034. "};\n",
  25035. "\n",
  25036. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  25037. " var width = fig.canvas.width/mpl.ratio\n",
  25038. " fig.root.unbind('remove')\n",
  25039. "\n",
  25040. " // Update the output cell to use the data from the current canvas.\n",
  25041. " fig.push_to_output();\n",
  25042. " var dataURL = fig.canvas.toDataURL();\n",
  25043. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  25044. " // the notebook keyboard shortcuts fail.\n",
  25045. " IPython.keyboard_manager.enable()\n",
  25046. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  25047. " fig.close_ws(fig, msg);\n",
  25048. "}\n",
  25049. "\n",
  25050. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  25051. " fig.send_message('closing', msg);\n",
  25052. " // fig.ws.close()\n",
  25053. "}\n",
  25054. "\n",
  25055. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  25056. " // Turn the data on the canvas into data in the output cell.\n",
  25057. " var width = this.canvas.width/mpl.ratio\n",
  25058. " var dataURL = this.canvas.toDataURL();\n",
  25059. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  25060. "}\n",
  25061. "\n",
  25062. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  25063. " // Tell IPython that the notebook contents must change.\n",
  25064. " IPython.notebook.set_dirty(true);\n",
  25065. " this.send_message(\"ack\", {});\n",
  25066. " var fig = this;\n",
  25067. " // Wait a second, then push the new image to the DOM so\n",
  25068. " // that it is saved nicely (might be nice to debounce this).\n",
  25069. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  25070. "}\n",
  25071. "\n",
  25072. "mpl.figure.prototype._init_toolbar = function() {\n",
  25073. " var fig = this;\n",
  25074. "\n",
  25075. " var nav_element = $('<div/>')\n",
  25076. " nav_element.attr('style', 'width: 100%');\n",
  25077. " this.root.append(nav_element);\n",
  25078. "\n",
  25079. " // Define a callback function for later on.\n",
  25080. " function toolbar_event(event) {\n",
  25081. " return fig.toolbar_button_onclick(event['data']);\n",
  25082. " }\n",
  25083. " function toolbar_mouse_event(event) {\n",
  25084. " return fig.toolbar_button_onmouseover(event['data']);\n",
  25085. " }\n",
  25086. "\n",
  25087. " for(var toolbar_ind in mpl.toolbar_items){\n",
  25088. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  25089. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  25090. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  25091. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  25092. "\n",
  25093. " if (!name) { continue; };\n",
  25094. "\n",
  25095. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  25096. " button.click(method_name, toolbar_event);\n",
  25097. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  25098. " nav_element.append(button);\n",
  25099. " }\n",
  25100. "\n",
  25101. " // Add the status bar.\n",
  25102. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  25103. " nav_element.append(status_bar);\n",
  25104. " this.message = status_bar[0];\n",
  25105. "\n",
  25106. " // Add the close button to the window.\n",
  25107. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  25108. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  25109. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  25110. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  25111. " buttongrp.append(button);\n",
  25112. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  25113. " titlebar.prepend(buttongrp);\n",
  25114. "}\n",
  25115. "\n",
  25116. "mpl.figure.prototype._root_extra_style = function(el){\n",
  25117. " var fig = this\n",
  25118. " el.on(\"remove\", function(){\n",
  25119. "\tfig.close_ws(fig, {});\n",
  25120. " });\n",
  25121. "}\n",
  25122. "\n",
  25123. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  25124. " // this is important to make the div 'focusable\n",
  25125. " el.attr('tabindex', 0)\n",
  25126. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  25127. " // off when our div gets focus\n",
  25128. "\n",
  25129. " // location in version 3\n",
  25130. " if (IPython.notebook.keyboard_manager) {\n",
  25131. " IPython.notebook.keyboard_manager.register_events(el);\n",
  25132. " }\n",
  25133. " else {\n",
  25134. " // location in version 2\n",
  25135. " IPython.keyboard_manager.register_events(el);\n",
  25136. " }\n",
  25137. "\n",
  25138. "}\n",
  25139. "\n",
  25140. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  25141. " var manager = IPython.notebook.keyboard_manager;\n",
  25142. " if (!manager)\n",
  25143. " manager = IPython.keyboard_manager;\n",
  25144. "\n",
  25145. " // Check for shift+enter\n",
  25146. " if (event.shiftKey && event.which == 13) {\n",
  25147. " this.canvas_div.blur();\n",
  25148. " event.shiftKey = false;\n",
  25149. " // Send a \"J\" for go to next cell\n",
  25150. " event.which = 74;\n",
  25151. " event.keyCode = 74;\n",
  25152. " manager.command_mode();\n",
  25153. " manager.handle_keydown(event);\n",
  25154. " }\n",
  25155. "}\n",
  25156. "\n",
  25157. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  25158. " fig.ondownload(fig, null);\n",
  25159. "}\n",
  25160. "\n",
  25161. "\n",
  25162. "mpl.find_output_cell = function(html_output) {\n",
  25163. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  25164. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  25165. " // IPython event is triggered only after the cells have been serialised, which for\n",
  25166. " // our purposes (turning an active figure into a static one), is too late.\n",
  25167. " var cells = IPython.notebook.get_cells();\n",
  25168. " var ncells = cells.length;\n",
  25169. " for (var i=0; i<ncells; i++) {\n",
  25170. " var cell = cells[i];\n",
  25171. " if (cell.cell_type === 'code'){\n",
  25172. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  25173. " var data = cell.output_area.outputs[j];\n",
  25174. " if (data.data) {\n",
  25175. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  25176. " data = data.data;\n",
  25177. " }\n",
  25178. " if (data['text/html'] == html_output) {\n",
  25179. " return [cell, data, j];\n",
  25180. " }\n",
  25181. " }\n",
  25182. " }\n",
  25183. " }\n",
  25184. "}\n",
  25185. "\n",
  25186. "// Register the function which deals with the matplotlib target/channel.\n",
  25187. "// The kernel may be null if the page has been refreshed.\n",
  25188. "if (IPython.notebook.kernel != null) {\n",
  25189. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  25190. "}\n"
  25191. ],
  25192. "text/plain": [
  25193. "<IPython.core.display.Javascript object>"
  25194. ]
  25195. },
  25196. "metadata": {},
  25197. "output_type": "display_data"
  25198. },
  25199. {
  25200. "data": {
  25201. "text/html": [
  25202. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  25203. ],
  25204. "text/plain": [
  25205. "<IPython.core.display.HTML object>"
  25206. ]
  25207. },
  25208. "metadata": {},
  25209. "output_type": "display_data"
  25210. },
  25211. {
  25212. "name": "stdout",
  25213. "output_type": "stream",
  25214. "text": [
  25215. "0.0 1.0\n",
  25216. "924.0\n",
  25217. "(343, 310)\n",
  25218. "\n"
  25219. ]
  25220. },
  25221. {
  25222. "data": {
  25223. "application/javascript": [
  25224. "/* Put everything inside the global mpl namespace */\n",
  25225. "window.mpl = {};\n",
  25226. "\n",
  25227. "\n",
  25228. "mpl.get_websocket_type = function() {\n",
  25229. " if (typeof(WebSocket) !== 'undefined') {\n",
  25230. " return WebSocket;\n",
  25231. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  25232. " return MozWebSocket;\n",
  25233. " } else {\n",
  25234. " alert('Your browser does not have WebSocket support.' +\n",
  25235. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  25236. " 'Firefox 4 and 5 are also supported but you ' +\n",
  25237. " 'have to enable WebSockets in about:config.');\n",
  25238. " };\n",
  25239. "}\n",
  25240. "\n",
  25241. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  25242. " this.id = figure_id;\n",
  25243. "\n",
  25244. " this.ws = websocket;\n",
  25245. "\n",
  25246. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  25247. "\n",
  25248. " if (!this.supports_binary) {\n",
  25249. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  25250. " if (warnings) {\n",
  25251. " warnings.style.display = 'block';\n",
  25252. " warnings.textContent = (\n",
  25253. " \"This browser does not support binary websocket messages. \" +\n",
  25254. " \"Performance may be slow.\");\n",
  25255. " }\n",
  25256. " }\n",
  25257. "\n",
  25258. " this.imageObj = new Image();\n",
  25259. "\n",
  25260. " this.context = undefined;\n",
  25261. " this.message = undefined;\n",
  25262. " this.canvas = undefined;\n",
  25263. " this.rubberband_canvas = undefined;\n",
  25264. " this.rubberband_context = undefined;\n",
  25265. " this.format_dropdown = undefined;\n",
  25266. "\n",
  25267. " this.image_mode = 'full';\n",
  25268. "\n",
  25269. " this.root = $('<div/>');\n",
  25270. " this._root_extra_style(this.root)\n",
  25271. " this.root.attr('style', 'display: inline-block');\n",
  25272. "\n",
  25273. " $(parent_element).append(this.root);\n",
  25274. "\n",
  25275. " this._init_header(this);\n",
  25276. " this._init_canvas(this);\n",
  25277. " this._init_toolbar(this);\n",
  25278. "\n",
  25279. " var fig = this;\n",
  25280. "\n",
  25281. " this.waiting = false;\n",
  25282. "\n",
  25283. " this.ws.onopen = function () {\n",
  25284. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  25285. " fig.send_message(\"send_image_mode\", {});\n",
  25286. " if (mpl.ratio != 1) {\n",
  25287. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  25288. " }\n",
  25289. " fig.send_message(\"refresh\", {});\n",
  25290. " }\n",
  25291. "\n",
  25292. " this.imageObj.onload = function() {\n",
  25293. " if (fig.image_mode == 'full') {\n",
  25294. " // Full images could contain transparency (where diff images\n",
  25295. " // almost always do), so we need to clear the canvas so that\n",
  25296. " // there is no ghosting.\n",
  25297. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  25298. " }\n",
  25299. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  25300. " };\n",
  25301. "\n",
  25302. " this.imageObj.onunload = function() {\n",
  25303. " fig.ws.close();\n",
  25304. " }\n",
  25305. "\n",
  25306. " this.ws.onmessage = this._make_on_message_function(this);\n",
  25307. "\n",
  25308. " this.ondownload = ondownload;\n",
  25309. "}\n",
  25310. "\n",
  25311. "mpl.figure.prototype._init_header = function() {\n",
  25312. " var titlebar = $(\n",
  25313. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  25314. " 'ui-helper-clearfix\"/>');\n",
  25315. " var titletext = $(\n",
  25316. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  25317. " 'text-align: center; padding: 3px;\"/>');\n",
  25318. " titlebar.append(titletext)\n",
  25319. " this.root.append(titlebar);\n",
  25320. " this.header = titletext[0];\n",
  25321. "}\n",
  25322. "\n",
  25323. "\n",
  25324. "\n",
  25325. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  25326. "\n",
  25327. "}\n",
  25328. "\n",
  25329. "\n",
  25330. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  25331. "\n",
  25332. "}\n",
  25333. "\n",
  25334. "mpl.figure.prototype._init_canvas = function() {\n",
  25335. " var fig = this;\n",
  25336. "\n",
  25337. " var canvas_div = $('<div/>');\n",
  25338. "\n",
  25339. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  25340. "\n",
  25341. " function canvas_keyboard_event(event) {\n",
  25342. " return fig.key_event(event, event['data']);\n",
  25343. " }\n",
  25344. "\n",
  25345. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  25346. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  25347. " this.canvas_div = canvas_div\n",
  25348. " this._canvas_extra_style(canvas_div)\n",
  25349. " this.root.append(canvas_div);\n",
  25350. "\n",
  25351. " var canvas = $('<canvas/>');\n",
  25352. " canvas.addClass('mpl-canvas');\n",
  25353. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  25354. "\n",
  25355. " this.canvas = canvas[0];\n",
  25356. " this.context = canvas[0].getContext(\"2d\");\n",
  25357. "\n",
  25358. " var backingStore = this.context.backingStorePixelRatio ||\n",
  25359. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  25360. "\tthis.context.mozBackingStorePixelRatio ||\n",
  25361. "\tthis.context.msBackingStorePixelRatio ||\n",
  25362. "\tthis.context.oBackingStorePixelRatio ||\n",
  25363. "\tthis.context.backingStorePixelRatio || 1;\n",
  25364. "\n",
  25365. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  25366. "\n",
  25367. " var rubberband = $('<canvas/>');\n",
  25368. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  25369. "\n",
  25370. " var pass_mouse_events = true;\n",
  25371. "\n",
  25372. " canvas_div.resizable({\n",
  25373. " start: function(event, ui) {\n",
  25374. " pass_mouse_events = false;\n",
  25375. " },\n",
  25376. " resize: function(event, ui) {\n",
  25377. " fig.request_resize(ui.size.width, ui.size.height);\n",
  25378. " },\n",
  25379. " stop: function(event, ui) {\n",
  25380. " pass_mouse_events = true;\n",
  25381. " fig.request_resize(ui.size.width, ui.size.height);\n",
  25382. " },\n",
  25383. " });\n",
  25384. "\n",
  25385. " function mouse_event_fn(event) {\n",
  25386. " if (pass_mouse_events)\n",
  25387. " return fig.mouse_event(event, event['data']);\n",
  25388. " }\n",
  25389. "\n",
  25390. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  25391. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  25392. " // Throttle sequential mouse events to 1 every 20ms.\n",
  25393. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  25394. "\n",
  25395. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  25396. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  25397. "\n",
  25398. " canvas_div.on(\"wheel\", function (event) {\n",
  25399. " event = event.originalEvent;\n",
  25400. " event['data'] = 'scroll'\n",
  25401. " if (event.deltaY < 0) {\n",
  25402. " event.step = 1;\n",
  25403. " } else {\n",
  25404. " event.step = -1;\n",
  25405. " }\n",
  25406. " mouse_event_fn(event);\n",
  25407. " });\n",
  25408. "\n",
  25409. " canvas_div.append(canvas);\n",
  25410. " canvas_div.append(rubberband);\n",
  25411. "\n",
  25412. " this.rubberband = rubberband;\n",
  25413. " this.rubberband_canvas = rubberband[0];\n",
  25414. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  25415. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  25416. "\n",
  25417. " this._resize_canvas = function(width, height) {\n",
  25418. " // Keep the size of the canvas, canvas container, and rubber band\n",
  25419. " // canvas in synch.\n",
  25420. " canvas_div.css('width', width)\n",
  25421. " canvas_div.css('height', height)\n",
  25422. "\n",
  25423. " canvas.attr('width', width * mpl.ratio);\n",
  25424. " canvas.attr('height', height * mpl.ratio);\n",
  25425. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  25426. "\n",
  25427. " rubberband.attr('width', width);\n",
  25428. " rubberband.attr('height', height);\n",
  25429. " }\n",
  25430. "\n",
  25431. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  25432. " // upon first draw.\n",
  25433. " this._resize_canvas(600, 600);\n",
  25434. "\n",
  25435. " // Disable right mouse context menu.\n",
  25436. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  25437. " return false;\n",
  25438. " });\n",
  25439. "\n",
  25440. " function set_focus () {\n",
  25441. " canvas.focus();\n",
  25442. " canvas_div.focus();\n",
  25443. " }\n",
  25444. "\n",
  25445. " window.setTimeout(set_focus, 100);\n",
  25446. "}\n",
  25447. "\n",
  25448. "mpl.figure.prototype._init_toolbar = function() {\n",
  25449. " var fig = this;\n",
  25450. "\n",
  25451. " var nav_element = $('<div/>')\n",
  25452. " nav_element.attr('style', 'width: 100%');\n",
  25453. " this.root.append(nav_element);\n",
  25454. "\n",
  25455. " // Define a callback function for later on.\n",
  25456. " function toolbar_event(event) {\n",
  25457. " return fig.toolbar_button_onclick(event['data']);\n",
  25458. " }\n",
  25459. " function toolbar_mouse_event(event) {\n",
  25460. " return fig.toolbar_button_onmouseover(event['data']);\n",
  25461. " }\n",
  25462. "\n",
  25463. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  25464. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  25465. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  25466. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  25467. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  25468. "\n",
  25469. " if (!name) {\n",
  25470. " // put a spacer in here.\n",
  25471. " continue;\n",
  25472. " }\n",
  25473. " var button = $('<button/>');\n",
  25474. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  25475. " 'ui-button-icon-only');\n",
  25476. " button.attr('role', 'button');\n",
  25477. " button.attr('aria-disabled', 'false');\n",
  25478. " button.click(method_name, toolbar_event);\n",
  25479. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  25480. "\n",
  25481. " var icon_img = $('<span/>');\n",
  25482. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  25483. " icon_img.addClass(image);\n",
  25484. " icon_img.addClass('ui-corner-all');\n",
  25485. "\n",
  25486. " var tooltip_span = $('<span/>');\n",
  25487. " tooltip_span.addClass('ui-button-text');\n",
  25488. " tooltip_span.html(tooltip);\n",
  25489. "\n",
  25490. " button.append(icon_img);\n",
  25491. " button.append(tooltip_span);\n",
  25492. "\n",
  25493. " nav_element.append(button);\n",
  25494. " }\n",
  25495. "\n",
  25496. " var fmt_picker_span = $('<span/>');\n",
  25497. "\n",
  25498. " var fmt_picker = $('<select/>');\n",
  25499. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  25500. " fmt_picker_span.append(fmt_picker);\n",
  25501. " nav_element.append(fmt_picker_span);\n",
  25502. " this.format_dropdown = fmt_picker[0];\n",
  25503. "\n",
  25504. " for (var ind in mpl.extensions) {\n",
  25505. " var fmt = mpl.extensions[ind];\n",
  25506. " var option = $(\n",
  25507. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  25508. " fmt_picker.append(option)\n",
  25509. " }\n",
  25510. "\n",
  25511. " // Add hover states to the ui-buttons\n",
  25512. " $( \".ui-button\" ).hover(\n",
  25513. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  25514. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  25515. " );\n",
  25516. "\n",
  25517. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  25518. " nav_element.append(status_bar);\n",
  25519. " this.message = status_bar[0];\n",
  25520. "}\n",
  25521. "\n",
  25522. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  25523. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  25524. " // which will in turn request a refresh of the image.\n",
  25525. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  25526. "}\n",
  25527. "\n",
  25528. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  25529. " properties['type'] = type;\n",
  25530. " properties['figure_id'] = this.id;\n",
  25531. " this.ws.send(JSON.stringify(properties));\n",
  25532. "}\n",
  25533. "\n",
  25534. "mpl.figure.prototype.send_draw_message = function() {\n",
  25535. " if (!this.waiting) {\n",
  25536. " this.waiting = true;\n",
  25537. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  25538. " }\n",
  25539. "}\n",
  25540. "\n",
  25541. "\n",
  25542. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  25543. " var format_dropdown = fig.format_dropdown;\n",
  25544. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  25545. " fig.ondownload(fig, format);\n",
  25546. "}\n",
  25547. "\n",
  25548. "\n",
  25549. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  25550. " var size = msg['size'];\n",
  25551. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  25552. " fig._resize_canvas(size[0], size[1]);\n",
  25553. " fig.send_message(\"refresh\", {});\n",
  25554. " };\n",
  25555. "}\n",
  25556. "\n",
  25557. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  25558. " var x0 = msg['x0'] / mpl.ratio;\n",
  25559. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  25560. " var x1 = msg['x1'] / mpl.ratio;\n",
  25561. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  25562. " x0 = Math.floor(x0) + 0.5;\n",
  25563. " y0 = Math.floor(y0) + 0.5;\n",
  25564. " x1 = Math.floor(x1) + 0.5;\n",
  25565. " y1 = Math.floor(y1) + 0.5;\n",
  25566. " var min_x = Math.min(x0, x1);\n",
  25567. " var min_y = Math.min(y0, y1);\n",
  25568. " var width = Math.abs(x1 - x0);\n",
  25569. " var height = Math.abs(y1 - y0);\n",
  25570. "\n",
  25571. " fig.rubberband_context.clearRect(\n",
  25572. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  25573. "\n",
  25574. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  25575. "}\n",
  25576. "\n",
  25577. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  25578. " // Updates the figure title.\n",
  25579. " fig.header.textContent = msg['label'];\n",
  25580. "}\n",
  25581. "\n",
  25582. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  25583. " var cursor = msg['cursor'];\n",
  25584. " switch(cursor)\n",
  25585. " {\n",
  25586. " case 0:\n",
  25587. " cursor = 'pointer';\n",
  25588. " break;\n",
  25589. " case 1:\n",
  25590. " cursor = 'default';\n",
  25591. " break;\n",
  25592. " case 2:\n",
  25593. " cursor = 'crosshair';\n",
  25594. " break;\n",
  25595. " case 3:\n",
  25596. " cursor = 'move';\n",
  25597. " break;\n",
  25598. " }\n",
  25599. " fig.rubberband_canvas.style.cursor = cursor;\n",
  25600. "}\n",
  25601. "\n",
  25602. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  25603. " fig.message.textContent = msg['message'];\n",
  25604. "}\n",
  25605. "\n",
  25606. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  25607. " // Request the server to send over a new figure.\n",
  25608. " fig.send_draw_message();\n",
  25609. "}\n",
  25610. "\n",
  25611. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  25612. " fig.image_mode = msg['mode'];\n",
  25613. "}\n",
  25614. "\n",
  25615. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  25616. " // Called whenever the canvas gets updated.\n",
  25617. " this.send_message(\"ack\", {});\n",
  25618. "}\n",
  25619. "\n",
  25620. "// A function to construct a web socket function for onmessage handling.\n",
  25621. "// Called in the figure constructor.\n",
  25622. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  25623. " return function socket_on_message(evt) {\n",
  25624. " if (evt.data instanceof Blob) {\n",
  25625. " /* FIXME: We get \"Resource interpreted as Image but\n",
  25626. " * transferred with MIME type text/plain:\" errors on\n",
  25627. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  25628. " * to be part of the websocket stream */\n",
  25629. " evt.data.type = \"image/png\";\n",
  25630. "\n",
  25631. " /* Free the memory for the previous frames */\n",
  25632. " if (fig.imageObj.src) {\n",
  25633. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  25634. " fig.imageObj.src);\n",
  25635. " }\n",
  25636. "\n",
  25637. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  25638. " evt.data);\n",
  25639. " fig.updated_canvas_event();\n",
  25640. " fig.waiting = false;\n",
  25641. " return;\n",
  25642. " }\n",
  25643. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  25644. " fig.imageObj.src = evt.data;\n",
  25645. " fig.updated_canvas_event();\n",
  25646. " fig.waiting = false;\n",
  25647. " return;\n",
  25648. " }\n",
  25649. "\n",
  25650. " var msg = JSON.parse(evt.data);\n",
  25651. " var msg_type = msg['type'];\n",
  25652. "\n",
  25653. " // Call the \"handle_{type}\" callback, which takes\n",
  25654. " // the figure and JSON message as its only arguments.\n",
  25655. " try {\n",
  25656. " var callback = fig[\"handle_\" + msg_type];\n",
  25657. " } catch (e) {\n",
  25658. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  25659. " return;\n",
  25660. " }\n",
  25661. "\n",
  25662. " if (callback) {\n",
  25663. " try {\n",
  25664. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  25665. " callback(fig, msg);\n",
  25666. " } catch (e) {\n",
  25667. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  25668. " }\n",
  25669. " }\n",
  25670. " };\n",
  25671. "}\n",
  25672. "\n",
  25673. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  25674. "mpl.findpos = function(e) {\n",
  25675. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  25676. " var targ;\n",
  25677. " if (!e)\n",
  25678. " e = window.event;\n",
  25679. " if (e.target)\n",
  25680. " targ = e.target;\n",
  25681. " else if (e.srcElement)\n",
  25682. " targ = e.srcElement;\n",
  25683. " if (targ.nodeType == 3) // defeat Safari bug\n",
  25684. " targ = targ.parentNode;\n",
  25685. "\n",
  25686. " // jQuery normalizes the pageX and pageY\n",
  25687. " // pageX,Y are the mouse positions relative to the document\n",
  25688. " // offset() returns the position of the element relative to the document\n",
  25689. " var x = e.pageX - $(targ).offset().left;\n",
  25690. " var y = e.pageY - $(targ).offset().top;\n",
  25691. "\n",
  25692. " return {\"x\": x, \"y\": y};\n",
  25693. "};\n",
  25694. "\n",
  25695. "/*\n",
  25696. " * return a copy of an object with only non-object keys\n",
  25697. " * we need this to avoid circular references\n",
  25698. " * http://stackoverflow.com/a/24161582/3208463\n",
  25699. " */\n",
  25700. "function simpleKeys (original) {\n",
  25701. " return Object.keys(original).reduce(function (obj, key) {\n",
  25702. " if (typeof original[key] !== 'object')\n",
  25703. " obj[key] = original[key]\n",
  25704. " return obj;\n",
  25705. " }, {});\n",
  25706. "}\n",
  25707. "\n",
  25708. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  25709. " var canvas_pos = mpl.findpos(event)\n",
  25710. "\n",
  25711. " if (name === 'button_press')\n",
  25712. " {\n",
  25713. " this.canvas.focus();\n",
  25714. " this.canvas_div.focus();\n",
  25715. " }\n",
  25716. "\n",
  25717. " var x = canvas_pos.x * mpl.ratio;\n",
  25718. " var y = canvas_pos.y * mpl.ratio;\n",
  25719. "\n",
  25720. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  25721. " step: event.step,\n",
  25722. " guiEvent: simpleKeys(event)});\n",
  25723. "\n",
  25724. " /* This prevents the web browser from automatically changing to\n",
  25725. " * the text insertion cursor when the button is pressed. We want\n",
  25726. " * to control all of the cursor setting manually through the\n",
  25727. " * 'cursor' event from matplotlib */\n",
  25728. " event.preventDefault();\n",
  25729. " return false;\n",
  25730. "}\n",
  25731. "\n",
  25732. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  25733. " // Handle any extra behaviour associated with a key event\n",
  25734. "}\n",
  25735. "\n",
  25736. "mpl.figure.prototype.key_event = function(event, name) {\n",
  25737. "\n",
  25738. " // Prevent repeat events\n",
  25739. " if (name == 'key_press')\n",
  25740. " {\n",
  25741. " if (event.which === this._key)\n",
  25742. " return;\n",
  25743. " else\n",
  25744. " this._key = event.which;\n",
  25745. " }\n",
  25746. " if (name == 'key_release')\n",
  25747. " this._key = null;\n",
  25748. "\n",
  25749. " var value = '';\n",
  25750. " if (event.ctrlKey && event.which != 17)\n",
  25751. " value += \"ctrl+\";\n",
  25752. " if (event.altKey && event.which != 18)\n",
  25753. " value += \"alt+\";\n",
  25754. " if (event.shiftKey && event.which != 16)\n",
  25755. " value += \"shift+\";\n",
  25756. "\n",
  25757. " value += 'k';\n",
  25758. " value += event.which.toString();\n",
  25759. "\n",
  25760. " this._key_event_extra(event, name);\n",
  25761. "\n",
  25762. " this.send_message(name, {key: value,\n",
  25763. " guiEvent: simpleKeys(event)});\n",
  25764. " return false;\n",
  25765. "}\n",
  25766. "\n",
  25767. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  25768. " if (name == 'download') {\n",
  25769. " this.handle_save(this, null);\n",
  25770. " } else {\n",
  25771. " this.send_message(\"toolbar_button\", {name: name});\n",
  25772. " }\n",
  25773. "};\n",
  25774. "\n",
  25775. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  25776. " this.message.textContent = tooltip;\n",
  25777. "};\n",
  25778. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  25779. "\n",
  25780. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  25781. "\n",
  25782. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  25783. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  25784. " // object with the appropriate methods. Currently this is a non binary\n",
  25785. " // socket, so there is still some room for performance tuning.\n",
  25786. " var ws = {};\n",
  25787. "\n",
  25788. " ws.close = function() {\n",
  25789. " comm.close()\n",
  25790. " };\n",
  25791. " ws.send = function(m) {\n",
  25792. " //console.log('sending', m);\n",
  25793. " comm.send(m);\n",
  25794. " };\n",
  25795. " // Register the callback with on_msg.\n",
  25796. " comm.on_msg(function(msg) {\n",
  25797. " //console.log('receiving', msg['content']['data'], msg);\n",
  25798. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  25799. " ws.onmessage(msg['content']['data'])\n",
  25800. " });\n",
  25801. " return ws;\n",
  25802. "}\n",
  25803. "\n",
  25804. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  25805. " // This is the function which gets called when the mpl process\n",
  25806. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  25807. "\n",
  25808. " var id = msg.content.data.id;\n",
  25809. " // Get hold of the div created by the display call when the Comm\n",
  25810. " // socket was opened in Python.\n",
  25811. " var element = $(\"#\" + id);\n",
  25812. " var ws_proxy = comm_websocket_adapter(comm)\n",
  25813. "\n",
  25814. " function ondownload(figure, format) {\n",
  25815. " window.open(figure.imageObj.src);\n",
  25816. " }\n",
  25817. "\n",
  25818. " var fig = new mpl.figure(id, ws_proxy,\n",
  25819. " ondownload,\n",
  25820. " element.get(0));\n",
  25821. "\n",
  25822. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  25823. " // web socket which is closed, not our websocket->open comm proxy.\n",
  25824. " ws_proxy.onopen();\n",
  25825. "\n",
  25826. " fig.parent_element = element.get(0);\n",
  25827. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  25828. " if (!fig.cell_info) {\n",
  25829. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  25830. " return;\n",
  25831. " }\n",
  25832. "\n",
  25833. " var output_index = fig.cell_info[2]\n",
  25834. " var cell = fig.cell_info[0];\n",
  25835. "\n",
  25836. "};\n",
  25837. "\n",
  25838. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  25839. " var width = fig.canvas.width/mpl.ratio\n",
  25840. " fig.root.unbind('remove')\n",
  25841. "\n",
  25842. " // Update the output cell to use the data from the current canvas.\n",
  25843. " fig.push_to_output();\n",
  25844. " var dataURL = fig.canvas.toDataURL();\n",
  25845. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  25846. " // the notebook keyboard shortcuts fail.\n",
  25847. " IPython.keyboard_manager.enable()\n",
  25848. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  25849. " fig.close_ws(fig, msg);\n",
  25850. "}\n",
  25851. "\n",
  25852. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  25853. " fig.send_message('closing', msg);\n",
  25854. " // fig.ws.close()\n",
  25855. "}\n",
  25856. "\n",
  25857. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  25858. " // Turn the data on the canvas into data in the output cell.\n",
  25859. " var width = this.canvas.width/mpl.ratio\n",
  25860. " var dataURL = this.canvas.toDataURL();\n",
  25861. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  25862. "}\n",
  25863. "\n",
  25864. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  25865. " // Tell IPython that the notebook contents must change.\n",
  25866. " IPython.notebook.set_dirty(true);\n",
  25867. " this.send_message(\"ack\", {});\n",
  25868. " var fig = this;\n",
  25869. " // Wait a second, then push the new image to the DOM so\n",
  25870. " // that it is saved nicely (might be nice to debounce this).\n",
  25871. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  25872. "}\n",
  25873. "\n",
  25874. "mpl.figure.prototype._init_toolbar = function() {\n",
  25875. " var fig = this;\n",
  25876. "\n",
  25877. " var nav_element = $('<div/>')\n",
  25878. " nav_element.attr('style', 'width: 100%');\n",
  25879. " this.root.append(nav_element);\n",
  25880. "\n",
  25881. " // Define a callback function for later on.\n",
  25882. " function toolbar_event(event) {\n",
  25883. " return fig.toolbar_button_onclick(event['data']);\n",
  25884. " }\n",
  25885. " function toolbar_mouse_event(event) {\n",
  25886. " return fig.toolbar_button_onmouseover(event['data']);\n",
  25887. " }\n",
  25888. "\n",
  25889. " for(var toolbar_ind in mpl.toolbar_items){\n",
  25890. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  25891. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  25892. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  25893. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  25894. "\n",
  25895. " if (!name) { continue; };\n",
  25896. "\n",
  25897. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  25898. " button.click(method_name, toolbar_event);\n",
  25899. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  25900. " nav_element.append(button);\n",
  25901. " }\n",
  25902. "\n",
  25903. " // Add the status bar.\n",
  25904. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  25905. " nav_element.append(status_bar);\n",
  25906. " this.message = status_bar[0];\n",
  25907. "\n",
  25908. " // Add the close button to the window.\n",
  25909. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  25910. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  25911. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  25912. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  25913. " buttongrp.append(button);\n",
  25914. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  25915. " titlebar.prepend(buttongrp);\n",
  25916. "}\n",
  25917. "\n",
  25918. "mpl.figure.prototype._root_extra_style = function(el){\n",
  25919. " var fig = this\n",
  25920. " el.on(\"remove\", function(){\n",
  25921. "\tfig.close_ws(fig, {});\n",
  25922. " });\n",
  25923. "}\n",
  25924. "\n",
  25925. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  25926. " // this is important to make the div 'focusable\n",
  25927. " el.attr('tabindex', 0)\n",
  25928. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  25929. " // off when our div gets focus\n",
  25930. "\n",
  25931. " // location in version 3\n",
  25932. " if (IPython.notebook.keyboard_manager) {\n",
  25933. " IPython.notebook.keyboard_manager.register_events(el);\n",
  25934. " }\n",
  25935. " else {\n",
  25936. " // location in version 2\n",
  25937. " IPython.keyboard_manager.register_events(el);\n",
  25938. " }\n",
  25939. "\n",
  25940. "}\n",
  25941. "\n",
  25942. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  25943. " var manager = IPython.notebook.keyboard_manager;\n",
  25944. " if (!manager)\n",
  25945. " manager = IPython.keyboard_manager;\n",
  25946. "\n",
  25947. " // Check for shift+enter\n",
  25948. " if (event.shiftKey && event.which == 13) {\n",
  25949. " this.canvas_div.blur();\n",
  25950. " event.shiftKey = false;\n",
  25951. " // Send a \"J\" for go to next cell\n",
  25952. " event.which = 74;\n",
  25953. " event.keyCode = 74;\n",
  25954. " manager.command_mode();\n",
  25955. " manager.handle_keydown(event);\n",
  25956. " }\n",
  25957. "}\n",
  25958. "\n",
  25959. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  25960. " fig.ondownload(fig, null);\n",
  25961. "}\n",
  25962. "\n",
  25963. "\n",
  25964. "mpl.find_output_cell = function(html_output) {\n",
  25965. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  25966. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  25967. " // IPython event is triggered only after the cells have been serialised, which for\n",
  25968. " // our purposes (turning an active figure into a static one), is too late.\n",
  25969. " var cells = IPython.notebook.get_cells();\n",
  25970. " var ncells = cells.length;\n",
  25971. " for (var i=0; i<ncells; i++) {\n",
  25972. " var cell = cells[i];\n",
  25973. " if (cell.cell_type === 'code'){\n",
  25974. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  25975. " var data = cell.output_area.outputs[j];\n",
  25976. " if (data.data) {\n",
  25977. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  25978. " data = data.data;\n",
  25979. " }\n",
  25980. " if (data['text/html'] == html_output) {\n",
  25981. " return [cell, data, j];\n",
  25982. " }\n",
  25983. " }\n",
  25984. " }\n",
  25985. " }\n",
  25986. "}\n",
  25987. "\n",
  25988. "// Register the function which deals with the matplotlib target/channel.\n",
  25989. "// The kernel may be null if the page has been refreshed.\n",
  25990. "if (IPython.notebook.kernel != null) {\n",
  25991. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  25992. "}\n"
  25993. ],
  25994. "text/plain": [
  25995. "<IPython.core.display.Javascript object>"
  25996. ]
  25997. },
  25998. "metadata": {},
  25999. "output_type": "display_data"
  26000. },
  26001. {
  26002. "data": {
  26003. "text/html": [
  26004. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  26005. ],
  26006. "text/plain": [
  26007. "<IPython.core.display.HTML object>"
  26008. ]
  26009. },
  26010. "metadata": {},
  26011. "output_type": "display_data"
  26012. },
  26013. {
  26014. "name": "stdout",
  26015. "output_type": "stream",
  26016. "text": [
  26017. "0 1\n",
  26018. "941\n",
  26019. "(344, 302)\n",
  26020. "\n"
  26021. ]
  26022. },
  26023. {
  26024. "data": {
  26025. "application/javascript": [
  26026. "/* Put everything inside the global mpl namespace */\n",
  26027. "window.mpl = {};\n",
  26028. "\n",
  26029. "\n",
  26030. "mpl.get_websocket_type = function() {\n",
  26031. " if (typeof(WebSocket) !== 'undefined') {\n",
  26032. " return WebSocket;\n",
  26033. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  26034. " return MozWebSocket;\n",
  26035. " } else {\n",
  26036. " alert('Your browser does not have WebSocket support.' +\n",
  26037. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  26038. " 'Firefox 4 and 5 are also supported but you ' +\n",
  26039. " 'have to enable WebSockets in about:config.');\n",
  26040. " };\n",
  26041. "}\n",
  26042. "\n",
  26043. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  26044. " this.id = figure_id;\n",
  26045. "\n",
  26046. " this.ws = websocket;\n",
  26047. "\n",
  26048. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  26049. "\n",
  26050. " if (!this.supports_binary) {\n",
  26051. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  26052. " if (warnings) {\n",
  26053. " warnings.style.display = 'block';\n",
  26054. " warnings.textContent = (\n",
  26055. " \"This browser does not support binary websocket messages. \" +\n",
  26056. " \"Performance may be slow.\");\n",
  26057. " }\n",
  26058. " }\n",
  26059. "\n",
  26060. " this.imageObj = new Image();\n",
  26061. "\n",
  26062. " this.context = undefined;\n",
  26063. " this.message = undefined;\n",
  26064. " this.canvas = undefined;\n",
  26065. " this.rubberband_canvas = undefined;\n",
  26066. " this.rubberband_context = undefined;\n",
  26067. " this.format_dropdown = undefined;\n",
  26068. "\n",
  26069. " this.image_mode = 'full';\n",
  26070. "\n",
  26071. " this.root = $('<div/>');\n",
  26072. " this._root_extra_style(this.root)\n",
  26073. " this.root.attr('style', 'display: inline-block');\n",
  26074. "\n",
  26075. " $(parent_element).append(this.root);\n",
  26076. "\n",
  26077. " this._init_header(this);\n",
  26078. " this._init_canvas(this);\n",
  26079. " this._init_toolbar(this);\n",
  26080. "\n",
  26081. " var fig = this;\n",
  26082. "\n",
  26083. " this.waiting = false;\n",
  26084. "\n",
  26085. " this.ws.onopen = function () {\n",
  26086. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  26087. " fig.send_message(\"send_image_mode\", {});\n",
  26088. " if (mpl.ratio != 1) {\n",
  26089. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  26090. " }\n",
  26091. " fig.send_message(\"refresh\", {});\n",
  26092. " }\n",
  26093. "\n",
  26094. " this.imageObj.onload = function() {\n",
  26095. " if (fig.image_mode == 'full') {\n",
  26096. " // Full images could contain transparency (where diff images\n",
  26097. " // almost always do), so we need to clear the canvas so that\n",
  26098. " // there is no ghosting.\n",
  26099. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  26100. " }\n",
  26101. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  26102. " };\n",
  26103. "\n",
  26104. " this.imageObj.onunload = function() {\n",
  26105. " fig.ws.close();\n",
  26106. " }\n",
  26107. "\n",
  26108. " this.ws.onmessage = this._make_on_message_function(this);\n",
  26109. "\n",
  26110. " this.ondownload = ondownload;\n",
  26111. "}\n",
  26112. "\n",
  26113. "mpl.figure.prototype._init_header = function() {\n",
  26114. " var titlebar = $(\n",
  26115. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  26116. " 'ui-helper-clearfix\"/>');\n",
  26117. " var titletext = $(\n",
  26118. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  26119. " 'text-align: center; padding: 3px;\"/>');\n",
  26120. " titlebar.append(titletext)\n",
  26121. " this.root.append(titlebar);\n",
  26122. " this.header = titletext[0];\n",
  26123. "}\n",
  26124. "\n",
  26125. "\n",
  26126. "\n",
  26127. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  26128. "\n",
  26129. "}\n",
  26130. "\n",
  26131. "\n",
  26132. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  26133. "\n",
  26134. "}\n",
  26135. "\n",
  26136. "mpl.figure.prototype._init_canvas = function() {\n",
  26137. " var fig = this;\n",
  26138. "\n",
  26139. " var canvas_div = $('<div/>');\n",
  26140. "\n",
  26141. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  26142. "\n",
  26143. " function canvas_keyboard_event(event) {\n",
  26144. " return fig.key_event(event, event['data']);\n",
  26145. " }\n",
  26146. "\n",
  26147. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  26148. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  26149. " this.canvas_div = canvas_div\n",
  26150. " this._canvas_extra_style(canvas_div)\n",
  26151. " this.root.append(canvas_div);\n",
  26152. "\n",
  26153. " var canvas = $('<canvas/>');\n",
  26154. " canvas.addClass('mpl-canvas');\n",
  26155. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  26156. "\n",
  26157. " this.canvas = canvas[0];\n",
  26158. " this.context = canvas[0].getContext(\"2d\");\n",
  26159. "\n",
  26160. " var backingStore = this.context.backingStorePixelRatio ||\n",
  26161. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  26162. "\tthis.context.mozBackingStorePixelRatio ||\n",
  26163. "\tthis.context.msBackingStorePixelRatio ||\n",
  26164. "\tthis.context.oBackingStorePixelRatio ||\n",
  26165. "\tthis.context.backingStorePixelRatio || 1;\n",
  26166. "\n",
  26167. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  26168. "\n",
  26169. " var rubberband = $('<canvas/>');\n",
  26170. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  26171. "\n",
  26172. " var pass_mouse_events = true;\n",
  26173. "\n",
  26174. " canvas_div.resizable({\n",
  26175. " start: function(event, ui) {\n",
  26176. " pass_mouse_events = false;\n",
  26177. " },\n",
  26178. " resize: function(event, ui) {\n",
  26179. " fig.request_resize(ui.size.width, ui.size.height);\n",
  26180. " },\n",
  26181. " stop: function(event, ui) {\n",
  26182. " pass_mouse_events = true;\n",
  26183. " fig.request_resize(ui.size.width, ui.size.height);\n",
  26184. " },\n",
  26185. " });\n",
  26186. "\n",
  26187. " function mouse_event_fn(event) {\n",
  26188. " if (pass_mouse_events)\n",
  26189. " return fig.mouse_event(event, event['data']);\n",
  26190. " }\n",
  26191. "\n",
  26192. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  26193. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  26194. " // Throttle sequential mouse events to 1 every 20ms.\n",
  26195. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  26196. "\n",
  26197. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  26198. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  26199. "\n",
  26200. " canvas_div.on(\"wheel\", function (event) {\n",
  26201. " event = event.originalEvent;\n",
  26202. " event['data'] = 'scroll'\n",
  26203. " if (event.deltaY < 0) {\n",
  26204. " event.step = 1;\n",
  26205. " } else {\n",
  26206. " event.step = -1;\n",
  26207. " }\n",
  26208. " mouse_event_fn(event);\n",
  26209. " });\n",
  26210. "\n",
  26211. " canvas_div.append(canvas);\n",
  26212. " canvas_div.append(rubberband);\n",
  26213. "\n",
  26214. " this.rubberband = rubberband;\n",
  26215. " this.rubberband_canvas = rubberband[0];\n",
  26216. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  26217. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  26218. "\n",
  26219. " this._resize_canvas = function(width, height) {\n",
  26220. " // Keep the size of the canvas, canvas container, and rubber band\n",
  26221. " // canvas in synch.\n",
  26222. " canvas_div.css('width', width)\n",
  26223. " canvas_div.css('height', height)\n",
  26224. "\n",
  26225. " canvas.attr('width', width * mpl.ratio);\n",
  26226. " canvas.attr('height', height * mpl.ratio);\n",
  26227. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  26228. "\n",
  26229. " rubberband.attr('width', width);\n",
  26230. " rubberband.attr('height', height);\n",
  26231. " }\n",
  26232. "\n",
  26233. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  26234. " // upon first draw.\n",
  26235. " this._resize_canvas(600, 600);\n",
  26236. "\n",
  26237. " // Disable right mouse context menu.\n",
  26238. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  26239. " return false;\n",
  26240. " });\n",
  26241. "\n",
  26242. " function set_focus () {\n",
  26243. " canvas.focus();\n",
  26244. " canvas_div.focus();\n",
  26245. " }\n",
  26246. "\n",
  26247. " window.setTimeout(set_focus, 100);\n",
  26248. "}\n",
  26249. "\n",
  26250. "mpl.figure.prototype._init_toolbar = function() {\n",
  26251. " var fig = this;\n",
  26252. "\n",
  26253. " var nav_element = $('<div/>')\n",
  26254. " nav_element.attr('style', 'width: 100%');\n",
  26255. " this.root.append(nav_element);\n",
  26256. "\n",
  26257. " // Define a callback function for later on.\n",
  26258. " function toolbar_event(event) {\n",
  26259. " return fig.toolbar_button_onclick(event['data']);\n",
  26260. " }\n",
  26261. " function toolbar_mouse_event(event) {\n",
  26262. " return fig.toolbar_button_onmouseover(event['data']);\n",
  26263. " }\n",
  26264. "\n",
  26265. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  26266. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  26267. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  26268. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  26269. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  26270. "\n",
  26271. " if (!name) {\n",
  26272. " // put a spacer in here.\n",
  26273. " continue;\n",
  26274. " }\n",
  26275. " var button = $('<button/>');\n",
  26276. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  26277. " 'ui-button-icon-only');\n",
  26278. " button.attr('role', 'button');\n",
  26279. " button.attr('aria-disabled', 'false');\n",
  26280. " button.click(method_name, toolbar_event);\n",
  26281. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  26282. "\n",
  26283. " var icon_img = $('<span/>');\n",
  26284. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  26285. " icon_img.addClass(image);\n",
  26286. " icon_img.addClass('ui-corner-all');\n",
  26287. "\n",
  26288. " var tooltip_span = $('<span/>');\n",
  26289. " tooltip_span.addClass('ui-button-text');\n",
  26290. " tooltip_span.html(tooltip);\n",
  26291. "\n",
  26292. " button.append(icon_img);\n",
  26293. " button.append(tooltip_span);\n",
  26294. "\n",
  26295. " nav_element.append(button);\n",
  26296. " }\n",
  26297. "\n",
  26298. " var fmt_picker_span = $('<span/>');\n",
  26299. "\n",
  26300. " var fmt_picker = $('<select/>');\n",
  26301. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  26302. " fmt_picker_span.append(fmt_picker);\n",
  26303. " nav_element.append(fmt_picker_span);\n",
  26304. " this.format_dropdown = fmt_picker[0];\n",
  26305. "\n",
  26306. " for (var ind in mpl.extensions) {\n",
  26307. " var fmt = mpl.extensions[ind];\n",
  26308. " var option = $(\n",
  26309. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  26310. " fmt_picker.append(option)\n",
  26311. " }\n",
  26312. "\n",
  26313. " // Add hover states to the ui-buttons\n",
  26314. " $( \".ui-button\" ).hover(\n",
  26315. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  26316. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  26317. " );\n",
  26318. "\n",
  26319. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  26320. " nav_element.append(status_bar);\n",
  26321. " this.message = status_bar[0];\n",
  26322. "}\n",
  26323. "\n",
  26324. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  26325. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  26326. " // which will in turn request a refresh of the image.\n",
  26327. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  26328. "}\n",
  26329. "\n",
  26330. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  26331. " properties['type'] = type;\n",
  26332. " properties['figure_id'] = this.id;\n",
  26333. " this.ws.send(JSON.stringify(properties));\n",
  26334. "}\n",
  26335. "\n",
  26336. "mpl.figure.prototype.send_draw_message = function() {\n",
  26337. " if (!this.waiting) {\n",
  26338. " this.waiting = true;\n",
  26339. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  26340. " }\n",
  26341. "}\n",
  26342. "\n",
  26343. "\n",
  26344. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  26345. " var format_dropdown = fig.format_dropdown;\n",
  26346. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  26347. " fig.ondownload(fig, format);\n",
  26348. "}\n",
  26349. "\n",
  26350. "\n",
  26351. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  26352. " var size = msg['size'];\n",
  26353. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  26354. " fig._resize_canvas(size[0], size[1]);\n",
  26355. " fig.send_message(\"refresh\", {});\n",
  26356. " };\n",
  26357. "}\n",
  26358. "\n",
  26359. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  26360. " var x0 = msg['x0'] / mpl.ratio;\n",
  26361. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  26362. " var x1 = msg['x1'] / mpl.ratio;\n",
  26363. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  26364. " x0 = Math.floor(x0) + 0.5;\n",
  26365. " y0 = Math.floor(y0) + 0.5;\n",
  26366. " x1 = Math.floor(x1) + 0.5;\n",
  26367. " y1 = Math.floor(y1) + 0.5;\n",
  26368. " var min_x = Math.min(x0, x1);\n",
  26369. " var min_y = Math.min(y0, y1);\n",
  26370. " var width = Math.abs(x1 - x0);\n",
  26371. " var height = Math.abs(y1 - y0);\n",
  26372. "\n",
  26373. " fig.rubberband_context.clearRect(\n",
  26374. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  26375. "\n",
  26376. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  26377. "}\n",
  26378. "\n",
  26379. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  26380. " // Updates the figure title.\n",
  26381. " fig.header.textContent = msg['label'];\n",
  26382. "}\n",
  26383. "\n",
  26384. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  26385. " var cursor = msg['cursor'];\n",
  26386. " switch(cursor)\n",
  26387. " {\n",
  26388. " case 0:\n",
  26389. " cursor = 'pointer';\n",
  26390. " break;\n",
  26391. " case 1:\n",
  26392. " cursor = 'default';\n",
  26393. " break;\n",
  26394. " case 2:\n",
  26395. " cursor = 'crosshair';\n",
  26396. " break;\n",
  26397. " case 3:\n",
  26398. " cursor = 'move';\n",
  26399. " break;\n",
  26400. " }\n",
  26401. " fig.rubberband_canvas.style.cursor = cursor;\n",
  26402. "}\n",
  26403. "\n",
  26404. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  26405. " fig.message.textContent = msg['message'];\n",
  26406. "}\n",
  26407. "\n",
  26408. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  26409. " // Request the server to send over a new figure.\n",
  26410. " fig.send_draw_message();\n",
  26411. "}\n",
  26412. "\n",
  26413. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  26414. " fig.image_mode = msg['mode'];\n",
  26415. "}\n",
  26416. "\n",
  26417. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  26418. " // Called whenever the canvas gets updated.\n",
  26419. " this.send_message(\"ack\", {});\n",
  26420. "}\n",
  26421. "\n",
  26422. "// A function to construct a web socket function for onmessage handling.\n",
  26423. "// Called in the figure constructor.\n",
  26424. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  26425. " return function socket_on_message(evt) {\n",
  26426. " if (evt.data instanceof Blob) {\n",
  26427. " /* FIXME: We get \"Resource interpreted as Image but\n",
  26428. " * transferred with MIME type text/plain:\" errors on\n",
  26429. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  26430. " * to be part of the websocket stream */\n",
  26431. " evt.data.type = \"image/png\";\n",
  26432. "\n",
  26433. " /* Free the memory for the previous frames */\n",
  26434. " if (fig.imageObj.src) {\n",
  26435. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  26436. " fig.imageObj.src);\n",
  26437. " }\n",
  26438. "\n",
  26439. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  26440. " evt.data);\n",
  26441. " fig.updated_canvas_event();\n",
  26442. " fig.waiting = false;\n",
  26443. " return;\n",
  26444. " }\n",
  26445. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  26446. " fig.imageObj.src = evt.data;\n",
  26447. " fig.updated_canvas_event();\n",
  26448. " fig.waiting = false;\n",
  26449. " return;\n",
  26450. " }\n",
  26451. "\n",
  26452. " var msg = JSON.parse(evt.data);\n",
  26453. " var msg_type = msg['type'];\n",
  26454. "\n",
  26455. " // Call the \"handle_{type}\" callback, which takes\n",
  26456. " // the figure and JSON message as its only arguments.\n",
  26457. " try {\n",
  26458. " var callback = fig[\"handle_\" + msg_type];\n",
  26459. " } catch (e) {\n",
  26460. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  26461. " return;\n",
  26462. " }\n",
  26463. "\n",
  26464. " if (callback) {\n",
  26465. " try {\n",
  26466. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  26467. " callback(fig, msg);\n",
  26468. " } catch (e) {\n",
  26469. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  26470. " }\n",
  26471. " }\n",
  26472. " };\n",
  26473. "}\n",
  26474. "\n",
  26475. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  26476. "mpl.findpos = function(e) {\n",
  26477. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  26478. " var targ;\n",
  26479. " if (!e)\n",
  26480. " e = window.event;\n",
  26481. " if (e.target)\n",
  26482. " targ = e.target;\n",
  26483. " else if (e.srcElement)\n",
  26484. " targ = e.srcElement;\n",
  26485. " if (targ.nodeType == 3) // defeat Safari bug\n",
  26486. " targ = targ.parentNode;\n",
  26487. "\n",
  26488. " // jQuery normalizes the pageX and pageY\n",
  26489. " // pageX,Y are the mouse positions relative to the document\n",
  26490. " // offset() returns the position of the element relative to the document\n",
  26491. " var x = e.pageX - $(targ).offset().left;\n",
  26492. " var y = e.pageY - $(targ).offset().top;\n",
  26493. "\n",
  26494. " return {\"x\": x, \"y\": y};\n",
  26495. "};\n",
  26496. "\n",
  26497. "/*\n",
  26498. " * return a copy of an object with only non-object keys\n",
  26499. " * we need this to avoid circular references\n",
  26500. " * http://stackoverflow.com/a/24161582/3208463\n",
  26501. " */\n",
  26502. "function simpleKeys (original) {\n",
  26503. " return Object.keys(original).reduce(function (obj, key) {\n",
  26504. " if (typeof original[key] !== 'object')\n",
  26505. " obj[key] = original[key]\n",
  26506. " return obj;\n",
  26507. " }, {});\n",
  26508. "}\n",
  26509. "\n",
  26510. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  26511. " var canvas_pos = mpl.findpos(event)\n",
  26512. "\n",
  26513. " if (name === 'button_press')\n",
  26514. " {\n",
  26515. " this.canvas.focus();\n",
  26516. " this.canvas_div.focus();\n",
  26517. " }\n",
  26518. "\n",
  26519. " var x = canvas_pos.x * mpl.ratio;\n",
  26520. " var y = canvas_pos.y * mpl.ratio;\n",
  26521. "\n",
  26522. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  26523. " step: event.step,\n",
  26524. " guiEvent: simpleKeys(event)});\n",
  26525. "\n",
  26526. " /* This prevents the web browser from automatically changing to\n",
  26527. " * the text insertion cursor when the button is pressed. We want\n",
  26528. " * to control all of the cursor setting manually through the\n",
  26529. " * 'cursor' event from matplotlib */\n",
  26530. " event.preventDefault();\n",
  26531. " return false;\n",
  26532. "}\n",
  26533. "\n",
  26534. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  26535. " // Handle any extra behaviour associated with a key event\n",
  26536. "}\n",
  26537. "\n",
  26538. "mpl.figure.prototype.key_event = function(event, name) {\n",
  26539. "\n",
  26540. " // Prevent repeat events\n",
  26541. " if (name == 'key_press')\n",
  26542. " {\n",
  26543. " if (event.which === this._key)\n",
  26544. " return;\n",
  26545. " else\n",
  26546. " this._key = event.which;\n",
  26547. " }\n",
  26548. " if (name == 'key_release')\n",
  26549. " this._key = null;\n",
  26550. "\n",
  26551. " var value = '';\n",
  26552. " if (event.ctrlKey && event.which != 17)\n",
  26553. " value += \"ctrl+\";\n",
  26554. " if (event.altKey && event.which != 18)\n",
  26555. " value += \"alt+\";\n",
  26556. " if (event.shiftKey && event.which != 16)\n",
  26557. " value += \"shift+\";\n",
  26558. "\n",
  26559. " value += 'k';\n",
  26560. " value += event.which.toString();\n",
  26561. "\n",
  26562. " this._key_event_extra(event, name);\n",
  26563. "\n",
  26564. " this.send_message(name, {key: value,\n",
  26565. " guiEvent: simpleKeys(event)});\n",
  26566. " return false;\n",
  26567. "}\n",
  26568. "\n",
  26569. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  26570. " if (name == 'download') {\n",
  26571. " this.handle_save(this, null);\n",
  26572. " } else {\n",
  26573. " this.send_message(\"toolbar_button\", {name: name});\n",
  26574. " }\n",
  26575. "};\n",
  26576. "\n",
  26577. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  26578. " this.message.textContent = tooltip;\n",
  26579. "};\n",
  26580. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  26581. "\n",
  26582. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  26583. "\n",
  26584. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  26585. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  26586. " // object with the appropriate methods. Currently this is a non binary\n",
  26587. " // socket, so there is still some room for performance tuning.\n",
  26588. " var ws = {};\n",
  26589. "\n",
  26590. " ws.close = function() {\n",
  26591. " comm.close()\n",
  26592. " };\n",
  26593. " ws.send = function(m) {\n",
  26594. " //console.log('sending', m);\n",
  26595. " comm.send(m);\n",
  26596. " };\n",
  26597. " // Register the callback with on_msg.\n",
  26598. " comm.on_msg(function(msg) {\n",
  26599. " //console.log('receiving', msg['content']['data'], msg);\n",
  26600. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  26601. " ws.onmessage(msg['content']['data'])\n",
  26602. " });\n",
  26603. " return ws;\n",
  26604. "}\n",
  26605. "\n",
  26606. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  26607. " // This is the function which gets called when the mpl process\n",
  26608. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  26609. "\n",
  26610. " var id = msg.content.data.id;\n",
  26611. " // Get hold of the div created by the display call when the Comm\n",
  26612. " // socket was opened in Python.\n",
  26613. " var element = $(\"#\" + id);\n",
  26614. " var ws_proxy = comm_websocket_adapter(comm)\n",
  26615. "\n",
  26616. " function ondownload(figure, format) {\n",
  26617. " window.open(figure.imageObj.src);\n",
  26618. " }\n",
  26619. "\n",
  26620. " var fig = new mpl.figure(id, ws_proxy,\n",
  26621. " ondownload,\n",
  26622. " element.get(0));\n",
  26623. "\n",
  26624. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  26625. " // web socket which is closed, not our websocket->open comm proxy.\n",
  26626. " ws_proxy.onopen();\n",
  26627. "\n",
  26628. " fig.parent_element = element.get(0);\n",
  26629. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  26630. " if (!fig.cell_info) {\n",
  26631. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  26632. " return;\n",
  26633. " }\n",
  26634. "\n",
  26635. " var output_index = fig.cell_info[2]\n",
  26636. " var cell = fig.cell_info[0];\n",
  26637. "\n",
  26638. "};\n",
  26639. "\n",
  26640. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  26641. " var width = fig.canvas.width/mpl.ratio\n",
  26642. " fig.root.unbind('remove')\n",
  26643. "\n",
  26644. " // Update the output cell to use the data from the current canvas.\n",
  26645. " fig.push_to_output();\n",
  26646. " var dataURL = fig.canvas.toDataURL();\n",
  26647. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  26648. " // the notebook keyboard shortcuts fail.\n",
  26649. " IPython.keyboard_manager.enable()\n",
  26650. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  26651. " fig.close_ws(fig, msg);\n",
  26652. "}\n",
  26653. "\n",
  26654. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  26655. " fig.send_message('closing', msg);\n",
  26656. " // fig.ws.close()\n",
  26657. "}\n",
  26658. "\n",
  26659. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  26660. " // Turn the data on the canvas into data in the output cell.\n",
  26661. " var width = this.canvas.width/mpl.ratio\n",
  26662. " var dataURL = this.canvas.toDataURL();\n",
  26663. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  26664. "}\n",
  26665. "\n",
  26666. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  26667. " // Tell IPython that the notebook contents must change.\n",
  26668. " IPython.notebook.set_dirty(true);\n",
  26669. " this.send_message(\"ack\", {});\n",
  26670. " var fig = this;\n",
  26671. " // Wait a second, then push the new image to the DOM so\n",
  26672. " // that it is saved nicely (might be nice to debounce this).\n",
  26673. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  26674. "}\n",
  26675. "\n",
  26676. "mpl.figure.prototype._init_toolbar = function() {\n",
  26677. " var fig = this;\n",
  26678. "\n",
  26679. " var nav_element = $('<div/>')\n",
  26680. " nav_element.attr('style', 'width: 100%');\n",
  26681. " this.root.append(nav_element);\n",
  26682. "\n",
  26683. " // Define a callback function for later on.\n",
  26684. " function toolbar_event(event) {\n",
  26685. " return fig.toolbar_button_onclick(event['data']);\n",
  26686. " }\n",
  26687. " function toolbar_mouse_event(event) {\n",
  26688. " return fig.toolbar_button_onmouseover(event['data']);\n",
  26689. " }\n",
  26690. "\n",
  26691. " for(var toolbar_ind in mpl.toolbar_items){\n",
  26692. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  26693. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  26694. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  26695. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  26696. "\n",
  26697. " if (!name) { continue; };\n",
  26698. "\n",
  26699. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  26700. " button.click(method_name, toolbar_event);\n",
  26701. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  26702. " nav_element.append(button);\n",
  26703. " }\n",
  26704. "\n",
  26705. " // Add the status bar.\n",
  26706. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  26707. " nav_element.append(status_bar);\n",
  26708. " this.message = status_bar[0];\n",
  26709. "\n",
  26710. " // Add the close button to the window.\n",
  26711. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  26712. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  26713. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  26714. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  26715. " buttongrp.append(button);\n",
  26716. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  26717. " titlebar.prepend(buttongrp);\n",
  26718. "}\n",
  26719. "\n",
  26720. "mpl.figure.prototype._root_extra_style = function(el){\n",
  26721. " var fig = this\n",
  26722. " el.on(\"remove\", function(){\n",
  26723. "\tfig.close_ws(fig, {});\n",
  26724. " });\n",
  26725. "}\n",
  26726. "\n",
  26727. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  26728. " // this is important to make the div 'focusable\n",
  26729. " el.attr('tabindex', 0)\n",
  26730. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  26731. " // off when our div gets focus\n",
  26732. "\n",
  26733. " // location in version 3\n",
  26734. " if (IPython.notebook.keyboard_manager) {\n",
  26735. " IPython.notebook.keyboard_manager.register_events(el);\n",
  26736. " }\n",
  26737. " else {\n",
  26738. " // location in version 2\n",
  26739. " IPython.keyboard_manager.register_events(el);\n",
  26740. " }\n",
  26741. "\n",
  26742. "}\n",
  26743. "\n",
  26744. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  26745. " var manager = IPython.notebook.keyboard_manager;\n",
  26746. " if (!manager)\n",
  26747. " manager = IPython.keyboard_manager;\n",
  26748. "\n",
  26749. " // Check for shift+enter\n",
  26750. " if (event.shiftKey && event.which == 13) {\n",
  26751. " this.canvas_div.blur();\n",
  26752. " event.shiftKey = false;\n",
  26753. " // Send a \"J\" for go to next cell\n",
  26754. " event.which = 74;\n",
  26755. " event.keyCode = 74;\n",
  26756. " manager.command_mode();\n",
  26757. " manager.handle_keydown(event);\n",
  26758. " }\n",
  26759. "}\n",
  26760. "\n",
  26761. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  26762. " fig.ondownload(fig, null);\n",
  26763. "}\n",
  26764. "\n",
  26765. "\n",
  26766. "mpl.find_output_cell = function(html_output) {\n",
  26767. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  26768. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  26769. " // IPython event is triggered only after the cells have been serialised, which for\n",
  26770. " // our purposes (turning an active figure into a static one), is too late.\n",
  26771. " var cells = IPython.notebook.get_cells();\n",
  26772. " var ncells = cells.length;\n",
  26773. " for (var i=0; i<ncells; i++) {\n",
  26774. " var cell = cells[i];\n",
  26775. " if (cell.cell_type === 'code'){\n",
  26776. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  26777. " var data = cell.output_area.outputs[j];\n",
  26778. " if (data.data) {\n",
  26779. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  26780. " data = data.data;\n",
  26781. " }\n",
  26782. " if (data['text/html'] == html_output) {\n",
  26783. " return [cell, data, j];\n",
  26784. " }\n",
  26785. " }\n",
  26786. " }\n",
  26787. " }\n",
  26788. "}\n",
  26789. "\n",
  26790. "// Register the function which deals with the matplotlib target/channel.\n",
  26791. "// The kernel may be null if the page has been refreshed.\n",
  26792. "if (IPython.notebook.kernel != null) {\n",
  26793. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  26794. "}\n"
  26795. ],
  26796. "text/plain": [
  26797. "<IPython.core.display.Javascript object>"
  26798. ]
  26799. },
  26800. "metadata": {},
  26801. "output_type": "display_data"
  26802. },
  26803. {
  26804. "data": {
  26805. "text/html": [
  26806. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  26807. ],
  26808. "text/plain": [
  26809. "<IPython.core.display.HTML object>"
  26810. ]
  26811. },
  26812. "metadata": {},
  26813. "output_type": "display_data"
  26814. },
  26815. {
  26816. "name": "stdout",
  26817. "output_type": "stream",
  26818. "text": [
  26819. "0.0 0.99999976\n",
  26820. "927.8574\n",
  26821. "(373, 310)\n",
  26822. "\n"
  26823. ]
  26824. },
  26825. {
  26826. "data": {
  26827. "application/javascript": [
  26828. "/* Put everything inside the global mpl namespace */\n",
  26829. "window.mpl = {};\n",
  26830. "\n",
  26831. "\n",
  26832. "mpl.get_websocket_type = function() {\n",
  26833. " if (typeof(WebSocket) !== 'undefined') {\n",
  26834. " return WebSocket;\n",
  26835. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  26836. " return MozWebSocket;\n",
  26837. " } else {\n",
  26838. " alert('Your browser does not have WebSocket support.' +\n",
  26839. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  26840. " 'Firefox 4 and 5 are also supported but you ' +\n",
  26841. " 'have to enable WebSockets in about:config.');\n",
  26842. " };\n",
  26843. "}\n",
  26844. "\n",
  26845. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  26846. " this.id = figure_id;\n",
  26847. "\n",
  26848. " this.ws = websocket;\n",
  26849. "\n",
  26850. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  26851. "\n",
  26852. " if (!this.supports_binary) {\n",
  26853. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  26854. " if (warnings) {\n",
  26855. " warnings.style.display = 'block';\n",
  26856. " warnings.textContent = (\n",
  26857. " \"This browser does not support binary websocket messages. \" +\n",
  26858. " \"Performance may be slow.\");\n",
  26859. " }\n",
  26860. " }\n",
  26861. "\n",
  26862. " this.imageObj = new Image();\n",
  26863. "\n",
  26864. " this.context = undefined;\n",
  26865. " this.message = undefined;\n",
  26866. " this.canvas = undefined;\n",
  26867. " this.rubberband_canvas = undefined;\n",
  26868. " this.rubberband_context = undefined;\n",
  26869. " this.format_dropdown = undefined;\n",
  26870. "\n",
  26871. " this.image_mode = 'full';\n",
  26872. "\n",
  26873. " this.root = $('<div/>');\n",
  26874. " this._root_extra_style(this.root)\n",
  26875. " this.root.attr('style', 'display: inline-block');\n",
  26876. "\n",
  26877. " $(parent_element).append(this.root);\n",
  26878. "\n",
  26879. " this._init_header(this);\n",
  26880. " this._init_canvas(this);\n",
  26881. " this._init_toolbar(this);\n",
  26882. "\n",
  26883. " var fig = this;\n",
  26884. "\n",
  26885. " this.waiting = false;\n",
  26886. "\n",
  26887. " this.ws.onopen = function () {\n",
  26888. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  26889. " fig.send_message(\"send_image_mode\", {});\n",
  26890. " if (mpl.ratio != 1) {\n",
  26891. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  26892. " }\n",
  26893. " fig.send_message(\"refresh\", {});\n",
  26894. " }\n",
  26895. "\n",
  26896. " this.imageObj.onload = function() {\n",
  26897. " if (fig.image_mode == 'full') {\n",
  26898. " // Full images could contain transparency (where diff images\n",
  26899. " // almost always do), so we need to clear the canvas so that\n",
  26900. " // there is no ghosting.\n",
  26901. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  26902. " }\n",
  26903. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  26904. " };\n",
  26905. "\n",
  26906. " this.imageObj.onunload = function() {\n",
  26907. " fig.ws.close();\n",
  26908. " }\n",
  26909. "\n",
  26910. " this.ws.onmessage = this._make_on_message_function(this);\n",
  26911. "\n",
  26912. " this.ondownload = ondownload;\n",
  26913. "}\n",
  26914. "\n",
  26915. "mpl.figure.prototype._init_header = function() {\n",
  26916. " var titlebar = $(\n",
  26917. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  26918. " 'ui-helper-clearfix\"/>');\n",
  26919. " var titletext = $(\n",
  26920. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  26921. " 'text-align: center; padding: 3px;\"/>');\n",
  26922. " titlebar.append(titletext)\n",
  26923. " this.root.append(titlebar);\n",
  26924. " this.header = titletext[0];\n",
  26925. "}\n",
  26926. "\n",
  26927. "\n",
  26928. "\n",
  26929. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  26930. "\n",
  26931. "}\n",
  26932. "\n",
  26933. "\n",
  26934. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  26935. "\n",
  26936. "}\n",
  26937. "\n",
  26938. "mpl.figure.prototype._init_canvas = function() {\n",
  26939. " var fig = this;\n",
  26940. "\n",
  26941. " var canvas_div = $('<div/>');\n",
  26942. "\n",
  26943. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  26944. "\n",
  26945. " function canvas_keyboard_event(event) {\n",
  26946. " return fig.key_event(event, event['data']);\n",
  26947. " }\n",
  26948. "\n",
  26949. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  26950. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  26951. " this.canvas_div = canvas_div\n",
  26952. " this._canvas_extra_style(canvas_div)\n",
  26953. " this.root.append(canvas_div);\n",
  26954. "\n",
  26955. " var canvas = $('<canvas/>');\n",
  26956. " canvas.addClass('mpl-canvas');\n",
  26957. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  26958. "\n",
  26959. " this.canvas = canvas[0];\n",
  26960. " this.context = canvas[0].getContext(\"2d\");\n",
  26961. "\n",
  26962. " var backingStore = this.context.backingStorePixelRatio ||\n",
  26963. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  26964. "\tthis.context.mozBackingStorePixelRatio ||\n",
  26965. "\tthis.context.msBackingStorePixelRatio ||\n",
  26966. "\tthis.context.oBackingStorePixelRatio ||\n",
  26967. "\tthis.context.backingStorePixelRatio || 1;\n",
  26968. "\n",
  26969. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  26970. "\n",
  26971. " var rubberband = $('<canvas/>');\n",
  26972. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  26973. "\n",
  26974. " var pass_mouse_events = true;\n",
  26975. "\n",
  26976. " canvas_div.resizable({\n",
  26977. " start: function(event, ui) {\n",
  26978. " pass_mouse_events = false;\n",
  26979. " },\n",
  26980. " resize: function(event, ui) {\n",
  26981. " fig.request_resize(ui.size.width, ui.size.height);\n",
  26982. " },\n",
  26983. " stop: function(event, ui) {\n",
  26984. " pass_mouse_events = true;\n",
  26985. " fig.request_resize(ui.size.width, ui.size.height);\n",
  26986. " },\n",
  26987. " });\n",
  26988. "\n",
  26989. " function mouse_event_fn(event) {\n",
  26990. " if (pass_mouse_events)\n",
  26991. " return fig.mouse_event(event, event['data']);\n",
  26992. " }\n",
  26993. "\n",
  26994. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  26995. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  26996. " // Throttle sequential mouse events to 1 every 20ms.\n",
  26997. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  26998. "\n",
  26999. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  27000. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  27001. "\n",
  27002. " canvas_div.on(\"wheel\", function (event) {\n",
  27003. " event = event.originalEvent;\n",
  27004. " event['data'] = 'scroll'\n",
  27005. " if (event.deltaY < 0) {\n",
  27006. " event.step = 1;\n",
  27007. " } else {\n",
  27008. " event.step = -1;\n",
  27009. " }\n",
  27010. " mouse_event_fn(event);\n",
  27011. " });\n",
  27012. "\n",
  27013. " canvas_div.append(canvas);\n",
  27014. " canvas_div.append(rubberband);\n",
  27015. "\n",
  27016. " this.rubberband = rubberband;\n",
  27017. " this.rubberband_canvas = rubberband[0];\n",
  27018. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  27019. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  27020. "\n",
  27021. " this._resize_canvas = function(width, height) {\n",
  27022. " // Keep the size of the canvas, canvas container, and rubber band\n",
  27023. " // canvas in synch.\n",
  27024. " canvas_div.css('width', width)\n",
  27025. " canvas_div.css('height', height)\n",
  27026. "\n",
  27027. " canvas.attr('width', width * mpl.ratio);\n",
  27028. " canvas.attr('height', height * mpl.ratio);\n",
  27029. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  27030. "\n",
  27031. " rubberband.attr('width', width);\n",
  27032. " rubberband.attr('height', height);\n",
  27033. " }\n",
  27034. "\n",
  27035. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  27036. " // upon first draw.\n",
  27037. " this._resize_canvas(600, 600);\n",
  27038. "\n",
  27039. " // Disable right mouse context menu.\n",
  27040. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  27041. " return false;\n",
  27042. " });\n",
  27043. "\n",
  27044. " function set_focus () {\n",
  27045. " canvas.focus();\n",
  27046. " canvas_div.focus();\n",
  27047. " }\n",
  27048. "\n",
  27049. " window.setTimeout(set_focus, 100);\n",
  27050. "}\n",
  27051. "\n",
  27052. "mpl.figure.prototype._init_toolbar = function() {\n",
  27053. " var fig = this;\n",
  27054. "\n",
  27055. " var nav_element = $('<div/>')\n",
  27056. " nav_element.attr('style', 'width: 100%');\n",
  27057. " this.root.append(nav_element);\n",
  27058. "\n",
  27059. " // Define a callback function for later on.\n",
  27060. " function toolbar_event(event) {\n",
  27061. " return fig.toolbar_button_onclick(event['data']);\n",
  27062. " }\n",
  27063. " function toolbar_mouse_event(event) {\n",
  27064. " return fig.toolbar_button_onmouseover(event['data']);\n",
  27065. " }\n",
  27066. "\n",
  27067. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  27068. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  27069. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  27070. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  27071. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  27072. "\n",
  27073. " if (!name) {\n",
  27074. " // put a spacer in here.\n",
  27075. " continue;\n",
  27076. " }\n",
  27077. " var button = $('<button/>');\n",
  27078. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  27079. " 'ui-button-icon-only');\n",
  27080. " button.attr('role', 'button');\n",
  27081. " button.attr('aria-disabled', 'false');\n",
  27082. " button.click(method_name, toolbar_event);\n",
  27083. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  27084. "\n",
  27085. " var icon_img = $('<span/>');\n",
  27086. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  27087. " icon_img.addClass(image);\n",
  27088. " icon_img.addClass('ui-corner-all');\n",
  27089. "\n",
  27090. " var tooltip_span = $('<span/>');\n",
  27091. " tooltip_span.addClass('ui-button-text');\n",
  27092. " tooltip_span.html(tooltip);\n",
  27093. "\n",
  27094. " button.append(icon_img);\n",
  27095. " button.append(tooltip_span);\n",
  27096. "\n",
  27097. " nav_element.append(button);\n",
  27098. " }\n",
  27099. "\n",
  27100. " var fmt_picker_span = $('<span/>');\n",
  27101. "\n",
  27102. " var fmt_picker = $('<select/>');\n",
  27103. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  27104. " fmt_picker_span.append(fmt_picker);\n",
  27105. " nav_element.append(fmt_picker_span);\n",
  27106. " this.format_dropdown = fmt_picker[0];\n",
  27107. "\n",
  27108. " for (var ind in mpl.extensions) {\n",
  27109. " var fmt = mpl.extensions[ind];\n",
  27110. " var option = $(\n",
  27111. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  27112. " fmt_picker.append(option)\n",
  27113. " }\n",
  27114. "\n",
  27115. " // Add hover states to the ui-buttons\n",
  27116. " $( \".ui-button\" ).hover(\n",
  27117. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  27118. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  27119. " );\n",
  27120. "\n",
  27121. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  27122. " nav_element.append(status_bar);\n",
  27123. " this.message = status_bar[0];\n",
  27124. "}\n",
  27125. "\n",
  27126. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  27127. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  27128. " // which will in turn request a refresh of the image.\n",
  27129. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  27130. "}\n",
  27131. "\n",
  27132. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  27133. " properties['type'] = type;\n",
  27134. " properties['figure_id'] = this.id;\n",
  27135. " this.ws.send(JSON.stringify(properties));\n",
  27136. "}\n",
  27137. "\n",
  27138. "mpl.figure.prototype.send_draw_message = function() {\n",
  27139. " if (!this.waiting) {\n",
  27140. " this.waiting = true;\n",
  27141. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  27142. " }\n",
  27143. "}\n",
  27144. "\n",
  27145. "\n",
  27146. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  27147. " var format_dropdown = fig.format_dropdown;\n",
  27148. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  27149. " fig.ondownload(fig, format);\n",
  27150. "}\n",
  27151. "\n",
  27152. "\n",
  27153. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  27154. " var size = msg['size'];\n",
  27155. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  27156. " fig._resize_canvas(size[0], size[1]);\n",
  27157. " fig.send_message(\"refresh\", {});\n",
  27158. " };\n",
  27159. "}\n",
  27160. "\n",
  27161. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  27162. " var x0 = msg['x0'] / mpl.ratio;\n",
  27163. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  27164. " var x1 = msg['x1'] / mpl.ratio;\n",
  27165. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  27166. " x0 = Math.floor(x0) + 0.5;\n",
  27167. " y0 = Math.floor(y0) + 0.5;\n",
  27168. " x1 = Math.floor(x1) + 0.5;\n",
  27169. " y1 = Math.floor(y1) + 0.5;\n",
  27170. " var min_x = Math.min(x0, x1);\n",
  27171. " var min_y = Math.min(y0, y1);\n",
  27172. " var width = Math.abs(x1 - x0);\n",
  27173. " var height = Math.abs(y1 - y0);\n",
  27174. "\n",
  27175. " fig.rubberband_context.clearRect(\n",
  27176. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  27177. "\n",
  27178. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  27179. "}\n",
  27180. "\n",
  27181. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  27182. " // Updates the figure title.\n",
  27183. " fig.header.textContent = msg['label'];\n",
  27184. "}\n",
  27185. "\n",
  27186. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  27187. " var cursor = msg['cursor'];\n",
  27188. " switch(cursor)\n",
  27189. " {\n",
  27190. " case 0:\n",
  27191. " cursor = 'pointer';\n",
  27192. " break;\n",
  27193. " case 1:\n",
  27194. " cursor = 'default';\n",
  27195. " break;\n",
  27196. " case 2:\n",
  27197. " cursor = 'crosshair';\n",
  27198. " break;\n",
  27199. " case 3:\n",
  27200. " cursor = 'move';\n",
  27201. " break;\n",
  27202. " }\n",
  27203. " fig.rubberband_canvas.style.cursor = cursor;\n",
  27204. "}\n",
  27205. "\n",
  27206. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  27207. " fig.message.textContent = msg['message'];\n",
  27208. "}\n",
  27209. "\n",
  27210. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  27211. " // Request the server to send over a new figure.\n",
  27212. " fig.send_draw_message();\n",
  27213. "}\n",
  27214. "\n",
  27215. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  27216. " fig.image_mode = msg['mode'];\n",
  27217. "}\n",
  27218. "\n",
  27219. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  27220. " // Called whenever the canvas gets updated.\n",
  27221. " this.send_message(\"ack\", {});\n",
  27222. "}\n",
  27223. "\n",
  27224. "// A function to construct a web socket function for onmessage handling.\n",
  27225. "// Called in the figure constructor.\n",
  27226. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  27227. " return function socket_on_message(evt) {\n",
  27228. " if (evt.data instanceof Blob) {\n",
  27229. " /* FIXME: We get \"Resource interpreted as Image but\n",
  27230. " * transferred with MIME type text/plain:\" errors on\n",
  27231. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  27232. " * to be part of the websocket stream */\n",
  27233. " evt.data.type = \"image/png\";\n",
  27234. "\n",
  27235. " /* Free the memory for the previous frames */\n",
  27236. " if (fig.imageObj.src) {\n",
  27237. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  27238. " fig.imageObj.src);\n",
  27239. " }\n",
  27240. "\n",
  27241. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  27242. " evt.data);\n",
  27243. " fig.updated_canvas_event();\n",
  27244. " fig.waiting = false;\n",
  27245. " return;\n",
  27246. " }\n",
  27247. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  27248. " fig.imageObj.src = evt.data;\n",
  27249. " fig.updated_canvas_event();\n",
  27250. " fig.waiting = false;\n",
  27251. " return;\n",
  27252. " }\n",
  27253. "\n",
  27254. " var msg = JSON.parse(evt.data);\n",
  27255. " var msg_type = msg['type'];\n",
  27256. "\n",
  27257. " // Call the \"handle_{type}\" callback, which takes\n",
  27258. " // the figure and JSON message as its only arguments.\n",
  27259. " try {\n",
  27260. " var callback = fig[\"handle_\" + msg_type];\n",
  27261. " } catch (e) {\n",
  27262. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  27263. " return;\n",
  27264. " }\n",
  27265. "\n",
  27266. " if (callback) {\n",
  27267. " try {\n",
  27268. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  27269. " callback(fig, msg);\n",
  27270. " } catch (e) {\n",
  27271. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  27272. " }\n",
  27273. " }\n",
  27274. " };\n",
  27275. "}\n",
  27276. "\n",
  27277. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  27278. "mpl.findpos = function(e) {\n",
  27279. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  27280. " var targ;\n",
  27281. " if (!e)\n",
  27282. " e = window.event;\n",
  27283. " if (e.target)\n",
  27284. " targ = e.target;\n",
  27285. " else if (e.srcElement)\n",
  27286. " targ = e.srcElement;\n",
  27287. " if (targ.nodeType == 3) // defeat Safari bug\n",
  27288. " targ = targ.parentNode;\n",
  27289. "\n",
  27290. " // jQuery normalizes the pageX and pageY\n",
  27291. " // pageX,Y are the mouse positions relative to the document\n",
  27292. " // offset() returns the position of the element relative to the document\n",
  27293. " var x = e.pageX - $(targ).offset().left;\n",
  27294. " var y = e.pageY - $(targ).offset().top;\n",
  27295. "\n",
  27296. " return {\"x\": x, \"y\": y};\n",
  27297. "};\n",
  27298. "\n",
  27299. "/*\n",
  27300. " * return a copy of an object with only non-object keys\n",
  27301. " * we need this to avoid circular references\n",
  27302. " * http://stackoverflow.com/a/24161582/3208463\n",
  27303. " */\n",
  27304. "function simpleKeys (original) {\n",
  27305. " return Object.keys(original).reduce(function (obj, key) {\n",
  27306. " if (typeof original[key] !== 'object')\n",
  27307. " obj[key] = original[key]\n",
  27308. " return obj;\n",
  27309. " }, {});\n",
  27310. "}\n",
  27311. "\n",
  27312. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  27313. " var canvas_pos = mpl.findpos(event)\n",
  27314. "\n",
  27315. " if (name === 'button_press')\n",
  27316. " {\n",
  27317. " this.canvas.focus();\n",
  27318. " this.canvas_div.focus();\n",
  27319. " }\n",
  27320. "\n",
  27321. " var x = canvas_pos.x * mpl.ratio;\n",
  27322. " var y = canvas_pos.y * mpl.ratio;\n",
  27323. "\n",
  27324. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  27325. " step: event.step,\n",
  27326. " guiEvent: simpleKeys(event)});\n",
  27327. "\n",
  27328. " /* This prevents the web browser from automatically changing to\n",
  27329. " * the text insertion cursor when the button is pressed. We want\n",
  27330. " * to control all of the cursor setting manually through the\n",
  27331. " * 'cursor' event from matplotlib */\n",
  27332. " event.preventDefault();\n",
  27333. " return false;\n",
  27334. "}\n",
  27335. "\n",
  27336. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  27337. " // Handle any extra behaviour associated with a key event\n",
  27338. "}\n",
  27339. "\n",
  27340. "mpl.figure.prototype.key_event = function(event, name) {\n",
  27341. "\n",
  27342. " // Prevent repeat events\n",
  27343. " if (name == 'key_press')\n",
  27344. " {\n",
  27345. " if (event.which === this._key)\n",
  27346. " return;\n",
  27347. " else\n",
  27348. " this._key = event.which;\n",
  27349. " }\n",
  27350. " if (name == 'key_release')\n",
  27351. " this._key = null;\n",
  27352. "\n",
  27353. " var value = '';\n",
  27354. " if (event.ctrlKey && event.which != 17)\n",
  27355. " value += \"ctrl+\";\n",
  27356. " if (event.altKey && event.which != 18)\n",
  27357. " value += \"alt+\";\n",
  27358. " if (event.shiftKey && event.which != 16)\n",
  27359. " value += \"shift+\";\n",
  27360. "\n",
  27361. " value += 'k';\n",
  27362. " value += event.which.toString();\n",
  27363. "\n",
  27364. " this._key_event_extra(event, name);\n",
  27365. "\n",
  27366. " this.send_message(name, {key: value,\n",
  27367. " guiEvent: simpleKeys(event)});\n",
  27368. " return false;\n",
  27369. "}\n",
  27370. "\n",
  27371. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  27372. " if (name == 'download') {\n",
  27373. " this.handle_save(this, null);\n",
  27374. " } else {\n",
  27375. " this.send_message(\"toolbar_button\", {name: name});\n",
  27376. " }\n",
  27377. "};\n",
  27378. "\n",
  27379. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  27380. " this.message.textContent = tooltip;\n",
  27381. "};\n",
  27382. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  27383. "\n",
  27384. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  27385. "\n",
  27386. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  27387. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  27388. " // object with the appropriate methods. Currently this is a non binary\n",
  27389. " // socket, so there is still some room for performance tuning.\n",
  27390. " var ws = {};\n",
  27391. "\n",
  27392. " ws.close = function() {\n",
  27393. " comm.close()\n",
  27394. " };\n",
  27395. " ws.send = function(m) {\n",
  27396. " //console.log('sending', m);\n",
  27397. " comm.send(m);\n",
  27398. " };\n",
  27399. " // Register the callback with on_msg.\n",
  27400. " comm.on_msg(function(msg) {\n",
  27401. " //console.log('receiving', msg['content']['data'], msg);\n",
  27402. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  27403. " ws.onmessage(msg['content']['data'])\n",
  27404. " });\n",
  27405. " return ws;\n",
  27406. "}\n",
  27407. "\n",
  27408. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  27409. " // This is the function which gets called when the mpl process\n",
  27410. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  27411. "\n",
  27412. " var id = msg.content.data.id;\n",
  27413. " // Get hold of the div created by the display call when the Comm\n",
  27414. " // socket was opened in Python.\n",
  27415. " var element = $(\"#\" + id);\n",
  27416. " var ws_proxy = comm_websocket_adapter(comm)\n",
  27417. "\n",
  27418. " function ondownload(figure, format) {\n",
  27419. " window.open(figure.imageObj.src);\n",
  27420. " }\n",
  27421. "\n",
  27422. " var fig = new mpl.figure(id, ws_proxy,\n",
  27423. " ondownload,\n",
  27424. " element.get(0));\n",
  27425. "\n",
  27426. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  27427. " // web socket which is closed, not our websocket->open comm proxy.\n",
  27428. " ws_proxy.onopen();\n",
  27429. "\n",
  27430. " fig.parent_element = element.get(0);\n",
  27431. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  27432. " if (!fig.cell_info) {\n",
  27433. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  27434. " return;\n",
  27435. " }\n",
  27436. "\n",
  27437. " var output_index = fig.cell_info[2]\n",
  27438. " var cell = fig.cell_info[0];\n",
  27439. "\n",
  27440. "};\n",
  27441. "\n",
  27442. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  27443. " var width = fig.canvas.width/mpl.ratio\n",
  27444. " fig.root.unbind('remove')\n",
  27445. "\n",
  27446. " // Update the output cell to use the data from the current canvas.\n",
  27447. " fig.push_to_output();\n",
  27448. " var dataURL = fig.canvas.toDataURL();\n",
  27449. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  27450. " // the notebook keyboard shortcuts fail.\n",
  27451. " IPython.keyboard_manager.enable()\n",
  27452. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  27453. " fig.close_ws(fig, msg);\n",
  27454. "}\n",
  27455. "\n",
  27456. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  27457. " fig.send_message('closing', msg);\n",
  27458. " // fig.ws.close()\n",
  27459. "}\n",
  27460. "\n",
  27461. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  27462. " // Turn the data on the canvas into data in the output cell.\n",
  27463. " var width = this.canvas.width/mpl.ratio\n",
  27464. " var dataURL = this.canvas.toDataURL();\n",
  27465. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  27466. "}\n",
  27467. "\n",
  27468. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  27469. " // Tell IPython that the notebook contents must change.\n",
  27470. " IPython.notebook.set_dirty(true);\n",
  27471. " this.send_message(\"ack\", {});\n",
  27472. " var fig = this;\n",
  27473. " // Wait a second, then push the new image to the DOM so\n",
  27474. " // that it is saved nicely (might be nice to debounce this).\n",
  27475. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  27476. "}\n",
  27477. "\n",
  27478. "mpl.figure.prototype._init_toolbar = function() {\n",
  27479. " var fig = this;\n",
  27480. "\n",
  27481. " var nav_element = $('<div/>')\n",
  27482. " nav_element.attr('style', 'width: 100%');\n",
  27483. " this.root.append(nav_element);\n",
  27484. "\n",
  27485. " // Define a callback function for later on.\n",
  27486. " function toolbar_event(event) {\n",
  27487. " return fig.toolbar_button_onclick(event['data']);\n",
  27488. " }\n",
  27489. " function toolbar_mouse_event(event) {\n",
  27490. " return fig.toolbar_button_onmouseover(event['data']);\n",
  27491. " }\n",
  27492. "\n",
  27493. " for(var toolbar_ind in mpl.toolbar_items){\n",
  27494. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  27495. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  27496. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  27497. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  27498. "\n",
  27499. " if (!name) { continue; };\n",
  27500. "\n",
  27501. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  27502. " button.click(method_name, toolbar_event);\n",
  27503. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  27504. " nav_element.append(button);\n",
  27505. " }\n",
  27506. "\n",
  27507. " // Add the status bar.\n",
  27508. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  27509. " nav_element.append(status_bar);\n",
  27510. " this.message = status_bar[0];\n",
  27511. "\n",
  27512. " // Add the close button to the window.\n",
  27513. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  27514. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  27515. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  27516. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  27517. " buttongrp.append(button);\n",
  27518. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  27519. " titlebar.prepend(buttongrp);\n",
  27520. "}\n",
  27521. "\n",
  27522. "mpl.figure.prototype._root_extra_style = function(el){\n",
  27523. " var fig = this\n",
  27524. " el.on(\"remove\", function(){\n",
  27525. "\tfig.close_ws(fig, {});\n",
  27526. " });\n",
  27527. "}\n",
  27528. "\n",
  27529. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  27530. " // this is important to make the div 'focusable\n",
  27531. " el.attr('tabindex', 0)\n",
  27532. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  27533. " // off when our div gets focus\n",
  27534. "\n",
  27535. " // location in version 3\n",
  27536. " if (IPython.notebook.keyboard_manager) {\n",
  27537. " IPython.notebook.keyboard_manager.register_events(el);\n",
  27538. " }\n",
  27539. " else {\n",
  27540. " // location in version 2\n",
  27541. " IPython.keyboard_manager.register_events(el);\n",
  27542. " }\n",
  27543. "\n",
  27544. "}\n",
  27545. "\n",
  27546. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  27547. " var manager = IPython.notebook.keyboard_manager;\n",
  27548. " if (!manager)\n",
  27549. " manager = IPython.keyboard_manager;\n",
  27550. "\n",
  27551. " // Check for shift+enter\n",
  27552. " if (event.shiftKey && event.which == 13) {\n",
  27553. " this.canvas_div.blur();\n",
  27554. " event.shiftKey = false;\n",
  27555. " // Send a \"J\" for go to next cell\n",
  27556. " event.which = 74;\n",
  27557. " event.keyCode = 74;\n",
  27558. " manager.command_mode();\n",
  27559. " manager.handle_keydown(event);\n",
  27560. " }\n",
  27561. "}\n",
  27562. "\n",
  27563. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  27564. " fig.ondownload(fig, null);\n",
  27565. "}\n",
  27566. "\n",
  27567. "\n",
  27568. "mpl.find_output_cell = function(html_output) {\n",
  27569. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  27570. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  27571. " // IPython event is triggered only after the cells have been serialised, which for\n",
  27572. " // our purposes (turning an active figure into a static one), is too late.\n",
  27573. " var cells = IPython.notebook.get_cells();\n",
  27574. " var ncells = cells.length;\n",
  27575. " for (var i=0; i<ncells; i++) {\n",
  27576. " var cell = cells[i];\n",
  27577. " if (cell.cell_type === 'code'){\n",
  27578. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  27579. " var data = cell.output_area.outputs[j];\n",
  27580. " if (data.data) {\n",
  27581. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  27582. " data = data.data;\n",
  27583. " }\n",
  27584. " if (data['text/html'] == html_output) {\n",
  27585. " return [cell, data, j];\n",
  27586. " }\n",
  27587. " }\n",
  27588. " }\n",
  27589. " }\n",
  27590. "}\n",
  27591. "\n",
  27592. "// Register the function which deals with the matplotlib target/channel.\n",
  27593. "// The kernel may be null if the page has been refreshed.\n",
  27594. "if (IPython.notebook.kernel != null) {\n",
  27595. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  27596. "}\n"
  27597. ],
  27598. "text/plain": [
  27599. "<IPython.core.display.Javascript object>"
  27600. ]
  27601. },
  27602. "metadata": {},
  27603. "output_type": "display_data"
  27604. },
  27605. {
  27606. "data": {
  27607. "text/html": [
  27608. "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA2AAAAJACAYAAADrSQUmAAAgAElEQVR4nO3de7TfdX3n+xcJKIiiCGqCEAggLYynWKFVQDCAyU5bGHVahiAsosjIaEFxvI2MrQGxCEnANTa9uNCOLrs459AuXWct6fRYPVrFVpHRApWIIIFcKBJQJtxE2s/54/sNbDa/3yaXnct7/x6PtZ5rme93/3Z+v+9Km7z4XXYCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEyh/ZN8Nsm6JL9IsirJJ5PsvQPvEwAAwLRzSJJ7k7QkX0ryiSRf63+9Msk+O+6uAQAATC9/m25sXTDh+JX98T/b7vcIAABgGjok3ci6M8mMCedekOShJA8n2XM73y8AAIBp59x0A+zPh5zf+OzYydvtHgEAAExTS9MNrPcNOf/H/fl3buH3vzPJ/UlulCSpaPen+/sMALbap9MNrHOHnP94f/7Dz/J9hv2l9cSMzGwvyIskSSrZjMxs6UYYAGy1bT3AHn5BXtTesMvvSZJUshfkRa3/Ow0Attq2fgnijQaYJKlyBhgAU2lbfwiHASZJKp0BBsBU2tYfQ2+ASZJKZ4ABMNW25Q9iNsAkSaUzwACYaockuTfd2PpSksuSfK3/9Y+S7LMV39sAkySVzgADYFs4IMlfJLknyeNJ7kryySR7b+X3NcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMIDR8XtJPpXkm0n+d5KW5AvPcptjk1yX5IEkjya5KcmFSWZOcptTknw9yYNJHkrynSSLt+J+j2eASZJKZ4ABjI4fpBtdG5LcmmcfYG9M8kS6EfWZJEuTrOxvd+2Q25zfn1+fZEWSq5Ks7o8t2+pHYIBJkopngAGMjhOTvCLJLknmZfIBtleSnyb5RZKjxx3fPcm3+9sumnCbg5I8luT+/n9vtHeS2/vbHLPldz+JASZJKp4BBjCa5mXyAXZOf/5zA86d1J/7xoTjl/THL97M77c5DDBJUukMMIDRNC+TD7Av9OfPGHBu1yQPJ/llkueOO/6tDH+Wa3Z/bvWW3d0nGWCSpNIZYACjaV4mH2A39OePGnL+lv784eOO3dcf22fIbR7qzz9vE+7fjUN62ACTJFXOAAMYTfMy+QC7rT9/6JDz1+eZz3Y93h/bdcht1vbnZ2/C/TPAJEnTMgMMYDTNy849wIbxEkRJUukMMIDRNC8790sQhzHAJEmlM8AARtO8+BAOSZK2ewYYwGiaFx9DL0nSds8AAxhN8/LsP4j5vmzeD2KeGz+IWZKkSTPAAEbHm5L8j77/mW4Q3THu2LIBX/9EuvduXZ3kiiQr+9tdm2SXAb/HBf359UlWJLkq3csO24DvvyUMMElS6QwwgNGxJN0QGtaqAbc5Lsl1SX6W5NEkNyd5b5KZk/w+p6Z7eeKGdO8VuyHJ4im4/4kBJkkqngEGQCUGmCSpdAYYAJUYYJKk0hlgAFRigEmSSmeAAVCJASZJKp0BBkAlBpgkqXQGGACVGGCSpNIZYABUYoBJkkpngAFQiQEmSSqdAQZAJQaYJKl0BhgAlRhgkqTSGWAAVGKASZJKZ4ABUIkBJkkqnQEGQCUGmCSpdAYYAJUYYJKk0hlgAFRigEmSSmeAAVCJASZJKp0BBkAlBpgkqXQGGACVGGCSpNIZYABUYoBJkkpngAFQiQEmSSqdAQZAJQaYJKl0BhgAlRhgkqTSGWAAVGKASZJKZ4ABUIkBJkkqnQEGQCUGmCSpdAYYAJUYYJKk0hlgAFRigEmSSmeAAVCJASZJKp0BBkAlBpgkqXQGGACVGGCSpNIZYABUYoBJkkpngAFQiQEmSSqdAQZAJQaYJKl0BhgAlRhgkqTSGWAAVGKASZJKZ4ABUIkBJkkqnQEGQCUGmCSpdAYYAJUYYJKk0hlgAFRigEmSSmeAAVCJASZJKp0BBkAlBpgkqXQGGACVGGCSpNIZYABUYoBJkkpngAFQiQEmSSqdAQZAJQaYJKl0BhgAlRhgkqTSGWAAVGKASZJKZ4ABUIkBJkkqnQEGQCUGmCSpdAYYAJUYYJKk0hlgAFRigEmSSmeAAVCJASZJKp0BBkAlBpgkqXQGGACVGGCSpNIZYABUYoBJkkpngAFQiQEmSSqdAQZAJQaYJKl0BhgAlRhgkqTSGWAAVGKASZJKZ4ABUIkBJkkqnQEGQCUGmCSpdAYYAJUYYJKk0hlgAFRigEmSSmeAAVCJASZJKp0BBkAlBpgkqXQGGACVGGCSpNIZYABUYoBJkkpngAFQiQEmSSqdAQZAJQaYJKl0BhgAlRhgkqTSGWAAVGKASZJKZ4ABjIZ9kpyb5ItJbk/yaJIHk3wryduTzBhyu2OTXJfkgf42NyW5MMnMSX6vU5J8vf/+DyX5TpLFW/sAegaYJKl0BhjAaPjPSVqSdUn+MsllST6b5Of98b9KssuE27wxyRPpRtRnkixNsrL/+muH/D7n9+fXJ1mR5Kokq/tjy6bgcRhgkqTSGWAAo+GkJKfmmc90zUpyd7qB9Lvjju+V5KdJfpHk6HHHd0/y7f7rF034XgcleSzJ/f3/3mjvdM+6tSTHbPlDSGKASZKKZ4ABcFG6cfSpccfO6Y99bsDXn9Sf+8aE45f0xy8ecJvJvt/mMMAkSaUzwAD4QLpxdNW4Y1/oj50x4Ot3TfJwkl8mee6449/K8Ge5ZvfnVm/lfTXAJEmlM8AARtuuSW5ON47Gxh2/oT921JDb3dKfP3zcsfv6Y/sMuc1D/fnnbcL9unFIDxtgkqTKGWAAo21ZulH05QnHb+uPHzrkdtfnmc92Pd4f23XIbdb252dvwv0ywCRJ0zIDDGB0vTvdILo1yYsnnNvRA2wYL0GUJJXOAAMYTRs/Lv6f030S4kQ7+iWIwxhgkqTSGWAAo+fCdEPo5iQvHfI1PoRDkqRtkAEGMFo+lG4IfT/JvpN8nY+hlyRpG2SAAYyOP0g3gr6XZ77na6K90r2kcHN+EPPc+EHMkiRNmgEGMBoWpxtAT6T7eV9LBvTWCbd5U//1DyW5OskVSVb23+faJLsM+H0u6M+vT7Ki/71W98eWTcHjMMAkSaUzwABGw5J0I2iyvj7gdscluS7Jz5I8mu59Y+9NMnOS3+vUdC9P3JDuvWI3pBuAU8EAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AARsflSb6aZHWSR5M8kOT7ST6aZJ8htzk2yXX91z6a5KYkFyaZOcnvc0qSryd5MMlDSb6TZPFW3/uOASZJKp0BBjA6Hk/yj0k+m+QTST6V5IYkLcnaJAdM+Po3Jnki3Yj6TJKlSVb2X3/tkN/j/P78+iQrklyVbvC1JMum4DEYYJKk0hlgAKNj9yHHP55uIP3JuGN7Jflpkl8kOXrC9/h2//WLJnyfg5I8luT+/n9vtHeS2/vbHLNF9/wpBpgkqXQGGABHphtHXxl37Jz+2OcGfP1J/blvTDh+SX/84gG3mez7bQ4DTJJUOgMMgI+kG0fLxx37Qn/sjAFfv2uSh5P8Mslzxx3/VoY/yzW7P7d6K++rASZJKp0BBjB63p9kSbr3Z30z3TD6pyQvGfc1G98bdtSQ73FLf/7wccfu648N+0CPh/rzz9uE+3jjkB42wCRJlTPAAEbPv6QbQhv7myQvm/A1t/XnDh3yPa7PM5/terw/tuuQ26ztz8/ehPtogEmSpmUGGMDoelmSNyf5UZJ1SV497tyOHmDDeAmiJKl0BhgAB6b7tMNbxh3b0S9BHMYAkySVzgADIOl+IHNLsm//ax/CIUnSNsgAAyBJ7k03kPbuf+1j6CVJ2gYZYACj4bAkLxxwfEae+kHM1487vle6lxRuzg9inhs/iFmSpEkzwABGw4VJHk33w5Y/neSyJJ9Ncke6YXRPkiMm3OZNSZ5I996tq5NckWRl//XXJtllwO9zQX9+fZIV6T7qfnV/bNkUPA4DTJJUOgMMYDS8MskfJ/lBunH0RJIH033YxpIkLx5yu+OSXJfkZ+kG3M1J3ptk5iS/16npXp64Id17xW5IsnhrH0DPAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcAkSaUzwACoxACTJJXOAAOgEgNMklQ6AwyASgwwSVLpDDAAKjHAJEmlM8AAqMQAkySVzgADoBIDTJJUOgMMgEoMMElS6QwwACoxwCRJpTPAAKjEAJMklc4AA6ASA0ySVDoDDIBKDDBJUukMMAAqMcCkUW/Gac/ejr6P0iQZYABUYoBJo9yM09qCPc9uC/Y8u83f/cw2f7dFT7X7mV3PeUt7w8zTu4wx7YQZYABUYoBJo1Y/uhbOubDN/82L2wkLP9FOPvZjbewVH2hjL31nG3vhOW3BXm9rC+dc2MZ+9b+2sV/5UFt4wHva2EvOawv2OKvN322RIaadKgMMgEoMMGmUmnFam7/7mW3hwe9rx/7u0nbEh65sR3zwyvYbZy1rJ7/u0rbw4Pe1sZec18Ze/J/a2K98qJ144h+143/78nbSCR9vY6/8b21s33e0BXuc1T0btqMfi9RngAFQiQEmjVIzTmtjLzynnTTv4+3gpcvbSV97b/uVv17SXvGx5e21/3Fpm3/0R7tnu176zjb2yv/WjjltaTviA1e2Iz5wZTv67OXds2Qv/k/dyxI9C6adJAMMgEoMMGmUmnFaW/D8xW3eGy5rh/xfl7T/fuuJ7SM3vbEd8aU/bL960ZXthN+6vI0d8eG2cP93twW//oft19+xvB34+T9qr/3bD7ZXXHtxO+G3Lm8L51zoWTDtVBlgAFRigEkj1vznvKUtOPIjbc6nL2+fv+017ct3/Lv2/h/8XjvoCx9vR75reTvp+Evb2K/+13bS8Ze2wz56ZTvt2+9of7ryhPbfbz2xveKSK9v837y4je39du8F006TAQZAJQaYNGrNOK2NveS89qrzlrcP/eA/tO+umtP++vZXtTP+4dx24Iql7ai3Lm8nzft4+80zl7VD/s+PtU+vfF27/s657fo757ZT//7321FvW+5ZMO1UGWAAVGKASaNY/16wE37r8nbNj49qX/3JYe2vb39V+8Ob/n37nb8/v736yxe15T98Q7tx1QHtrtWz2j1rZrc1q2e1m+56efvMj45tB31yWXvDMZc89X6wHf14NNIZYABUYoBJo9rM09vYS85rr/3bD7ZPr3xd++vbX9X+8rbfaH+68oT2Fz96bbvt7lnt3jWz2wNrX94eWPvytn7Nfm3N6lntlrv2a59e+bp24KeWtpOP+1gb2/vtO/6xaKQzwACoxACTRrj5uy1qR75refudvz+/feZHx7a/uePwdv2dc9utd3fDa8PaOU/rgbUvb/esmd1uu3tWu+bHR7U5f35Fm3/0R70XTDs0AwyASgwwacRb8H98pB24Ymn7xD+PtevvnNvuXD2rrV+zX3tk3YHtsXVzn9aGtXPag2v3b+vX7Nduv3tW+79//Op28OXL2/zdzzTCtMMywACoxACTRryxfd/Rfu2CK9uH/+nNTz7z9ci6A9vj6w5+Ro+tm9seWXfgk8+G3bl6VvvTlSe0hbN/36ciaodlgAFQiQEmjXjzdz+zHffmK9rnb3tN27B2zpNj61/vOXRo48fYA2tf3s757uJ2zGlL29hL3+mHNGu7Z4ABUIkBJo1483c/sx199vL23VVz2mPr5k46vCaOsMfXHdweWXdgu/3uWe3D//TmduS7lreFc/9L9xH1Rpi2UwYYAJUYYNKIt2DPs9uhf7S83btm9iaPr4lD7MG1+7e7Vs9qf3nbb7SDly5vC478SFvw/MU7/LFpNDLAAKjEAJNGvLFZ72pn/MO5m/Xs18Q2fkDHvWtmt//vzkPb3GsubSe/7lI/qFnbJQMMgEoMMGnEm/eGy9qtd2/Zs1+D3hO2fs1+7ft37d9O+Lv3eU+YtksGGACVGGDSiPeKay/eqme/Bg2xB9a+vN1296zuPWEHv8/H1GubZoABUIkBJo1wYy88pz2y7sApGV+Dxtg9a2a3v7nj8Dbnz65oY0d8uHs2bCd43JpeGWAAVGKASaPazNPb2GEf3Cbja2OPrDvwyRF26KXL29isd+34x61plwEGQCUGmDSizd9tUTv+ty/fpgNs48fUr1k9q33yhye343/78h3+uDX9MsAAqMQAk0a0+c95S3vVecu36QDbOMI2rJ3Tbrt7Vpvz51d4L5imPAMMgEoMMGlEm/+ct7TDlly5zQfYv95z6JMfzHHxzaf4aHpNeQYYAJUYYNKItmCPs9qBn7tsuwywjS9FvP7OuW3+bot2+GPX9MoAA6ASA0waxWac1hYe/L721Z8ctl0G2MZnwW69e7ZPQtSUZ4ABUIkBJo1iM09vr/2PS9v6Nftt1wF2zY+P8hJETXkGGACVGGDSCLZgz7Pb3GsunbIfwLwpL0G8a/WsdtBVy3wIh6Y8AwyASgwwaQRbuP+72/IfvmG7ja971sxuB19zaVs458Id/tg1/TLAAKjEAJNGrRmntQWv+oN2/Z3b/tmvx9cd3G69e3Y7eOnytnD273v2S9skAwyASgwwacSav9uidvzvXN5uuWvbvv/rkXUHthNP/KM2f/czd/hj1vTOAAOgEgNMGrHm77aonfBbl7fvrprTHl938DYZXw+u3b+d972zfOKhtksGGACVGGDSiDV/t0Xt5OM+1q758VFTPsAeX3dwW79mv3bmP57TTj7uYzv8sWo0MsAAqMQAk0atmae3sV/5UDvt2+9oG9bOmbLh9ci6A9udq2e1M/7h3Hb871zeFux59o5/rBqJDDAAKjHApFFrxmlt7CXntUM+sbx9/679N3lgbRxZg7pnzez21Z8c1o77fz/QXrNoWRvb9x0+cEPbLQMMgEoMMGkEW7DHWe2k4y9tx3/l/e2BtS9/2ph6bN3cJ9uwdk67Z83sdtNdL2//zx2vbEv/eUFbcevr2xdv/7V246oD2u13z2q33z2rfegH/6Ed+Kml7fVjn2hjL31nm7/boh3+GDU6GWAAVGKASSPa/N0WtbF939GOOW1p+/V3LG+/9vtXtlf+lyvbKz62vM350yvaoR9f3l5zxrK24Nf/sC3c7/w2tvfb24LnL25jLzynLdz/3e3kYz/Wjnrr8nbku5a3hQe8p/vADc96aQdkgAFQiQEmjXDzd1vUxl5yXlu4/7vbwoPe2xYe8v429u8uavNf/dE2dtgH29hL39kWPH9xm/+ct3TPas08vc3fbVGb/5y3dENsv/Pbwv3f3d4w8/Qd/lg0uhlgAFRigEkj3vzdFrX5u5/ZFuxxVlvw/MVde72te0Zr5unds1rjn9na+Ot+jBlf2tEZYABUYoBJetqoenJ07ej7JG1iBhgAlRhgkqTSGWAAVGKASZJKZ4ABUIkBJkkqnQEGQCUGmCSpdAYYAJUYYJKk0hlgAKPtrCSt79whX3NKkq8neTDJQ0m+k2Txs3zfxUm+23/9g/3tT9nqe2uASZKKZ4ABjK4Dkvw8yYYMH2Dn9+fWJ1mR5Kokq/tjy4Z832X9+dX9169Icn9/7PytvM8GmCSpdAYYwGjaJcnfJbkjydIMHmAHJXks3Xg6aNzxvZPc3t/mmAm3ObY/fnv/deO/1/399zsoW84AkySVzgADGE3vSfJvSU5IsiSDB9gl/fGLB9z+nP7c5yYc/3x//G0DbjPZ99tUBpgkqXQGGMDoOTzJo+leHpgMH2DfyuBnuZJkdp56meF4a/rjswfc5pj+3De35E73DDBJUukMMIDRsmuS7yX5UZI9+mNLMniA3dcf32fI93qoP/+8/td79r/eMOTr9+3P37sJ9/PGIT1sgEmSKmeAAYyWS5L8a57+rNaSDB5gj/fHdx3yvdbm6c927df/es2Qr9+tP/+LTbifBpgkaVpmgAGMjtckeSLJFROOL8nON8CG8RJESVLpDDCA0bBrupcd/jDJcyecW5Kd7yWIwxhgkqTSGWAAo+FFeeoHLj9bn+xv40M4JEma4gwwgNGwR5Krh/S/8tQwujrJ6f1tfAy9JElTnAEGwJIMfgni3PhBzJIkTWkGGABLMniAJckF/bn1SVak+9lhq/tjy4Z8v+V56uWJV/W3W98fO38r76sBJkkqnQEGwJIMH2BJcmqSb6T7cI2Hk9yQZPGzfM+39l/3cH+7byQ5ZevvqgEmSaqdAQZAJQaYJKl0BhgAlRhgkqTSGWAAVGKASZJKZ4ABUIkBJkkqnQEGQCUGmCSpdAYYAJUYYJKk0hlgAFRigEmSSmeAAVCJASZJKp0BBkAlBpgkqXQGGACVGGCSpNIZYABUYoBJkkpngAFQiQEmSSqdAQZAJQaYJKl0BhgAlRhgkqTSGWAAVGKASZJKZ4ABUIkBJkkqnQEGQCUGmCSpdAYYAJUYYJKk0hlgAFRigEmSSmeAAVCJASZJKp0BBkAlBpgkqXQGGACVGGCSpNIZYABUYoBJkkpngAFQiQEmSSqdAQZAJQaYJKl0BhgAlRhgkqTSGWAAVGKASZJKZ4ABUIkBJkkqnQEGQCUGmCSpdAYYAJUYYJKk0hlgAFRigEmSSmeAAVCJASZJKp0BBkAlBpgkqXQGGACVGGCSpNIZYABUYoBJkkpngAFQiQEmSSqdAQZAJQaYJKl0BhgAlRhgkqTSGWAAVGKASZJKZ4ABUIkBJkkqnQEGQCUGmCSpdAYYAJUYYJKk0hlgAFRigEmSSmeAAVCJASZJKp0BBkAlBpgkqXQGGACVGGCSpNIZYABUYoBJkkpngAFQiQEmSSqdAQZAJQaYJKl0BhgAlRhgkqTSGWAAVGKASZJKZ4ABUIkBJkkqnQEGQCUGmCSpdAYYAJUYYJKk0hlgAFRigEmSSmeAAVCJASZJKp0BBkAlBpgkqXQGGACVGGCSpNIZYABUYoBJkq1/mP8AAAreSURBVEpngAFQiQEmSSqdAQZAJQaYJKl0BhgAlRhgkqTSGWAAVGKASZJKZ4ABUIkBJkkqnQEGQCUGmCSpdAYYAJUYYJKk0hlgAFRigEmSSmeAAVCJASZJKp0BBkAlBpgkqXQGGACVGGCSpNIZYABUYoBJkkpngAGMjlVJ2pD+Zchtjk1yXZIHkjya5KYkFyaZOcnvc0qSryd5MMlDSb6TZPHW3vmeASZJKp0BBjA6ViX5eZIlA3r/gK9/Y5In0o2ozyRZmmRlusF27ZDf4/z+/PokK5JclWR1f2zZVj8CA0ySVDwDDGB0rOrbFHsl+WmSXyQ5etzx3ZN8O92gWjThNgcleSzJ/f3/3mjvJLf3tzlms+7xMxlgkqTSGWAAo2NVNn2AnZNuMH1uwLmT+nPfmHD8kv74xZv5/TaHASZJKp0BBjA6ViW5J8lZSS5K8p4kJ2bw+7m+kG4wnTHg3K5JHk7yyyTPHXf8Wxn+LNfs/tzqLbvrTzLAJEmlM8AARseqDP4Ajp8kef2Er72hP3fUkO91S3/+8HHH7uuP7TPkNg/155+3Cff1xiE9bIBJkipngAGMjo+me/ngy9KNoFcm+bMk/5bkkSRHjvva29KNpUOHfK/r88xnux7vj+065DZr+/OzN+G+GmCSpGmZAQbAsnTD6Ivjju3oATaMlyBKkkpngAFwaLphdP+4Yzv6JYjDGGCSpNIZYAC8MN0wemzcMR/CIUnSNsgAA2As3Tj64bhjPoZekqRtkAEGMBoOT7LngOMHJflxunF00bjje6V7SeHm/CDmufGDmCVJmjQDDGA0LEmyIcmXk/xJksuT/FWSR9MNoy8nec6E27wpyRPp3rt1dZIrkqzsv/7aJLsM+H0u6M+vT7IiyVXpXnbY0n3Yx9YywCRJpTPAAEbD65Nck25A/Tzd+7fuS/KVJGdn8JhKkuOSXJfkZ+nG2s1J3pvBP7x5o1PTvTxxQ7r3it2QZPFWP4KOASZJKp0BBkAlBpgkqXQGGACV3D8jM9sL8iJJkko2IzMn/ugXANhp3ZnufWkPp/uvh5qaHnZNXdMCuaau6c7epl7P+9P9fQYAJWz8C4yp45pOPdd06rmmU881nVquJwDTkr/gpp5rOvVc06nnmk4913RquZ4ATEv+gpt6runUc02nnms69VzTqeV6AjAt+Qtu6rmmU881nXqu6dRzTaeW6wnAtOQvuKnnmk4913TquaZTzzWdWq4nANOSv+Cmnms69VzTqeeaTj3XdGq5ngAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjbv8kn02yLskvkqxK8skke+/A+7Sz+L0kn0ryzST/O0lL8oVnuc2xSa5L8kCSR5PclOTCJDMnuc0pSb6e5MEkDyX5TpLFW3G/d1b7JDk3yReT3J7u+jyY5FtJ3p5kxpDbuaaTuzzJV5OsTnd9Hkjy/SQfTXfNB3FNN89Z6f7vv6X7MzzIllyfxUm+23/9g/3tT9nqe7tzWpWnruHE/mXIbfw5BWDaOSTJven+AvxSkk8k+Vr/65UZ/o+3UfGDdNdiQ5Jb8+wD7I1Jnkj3l/5nkixNdx1bkmuH3Ob8/vz6JCuSXJXuH9ItybKtfgQ7l/+c7nGtS/KXSS5LN/5/3h//qyS7TLiNa/rsHk/yj+mu5SfS/UeDG9I93rVJDpjw9a7p5jkg3Z/RDRk+wLbk+izrz6/uv35Fkvv7Y+dP3d3faaxKdx2XDOj9A77en1MApqW/TfcX0wUTjl/ZH/+z7X6Pdi4nJnlFulEwL5MPsL2S/DTds4hHjzu+e5Jv97ddNOE2ByV5LN0/ug4ad3zvdM8QtSTHbPnd3+mclOTUPPOZrllJ7k73eH933HHXdNPsPuT4x9M93j8Zd8w13Ty7JPm7JHekGwCDBthB2fzrc2x//PY8/dUGB/Xf57EJ32s6WNW3Kfw5BWBaOiTdX0h35pn/IH5Buv/q+HCSPbfz/dpZzcvkA+yc/vznBpw7qT/3jQnHL+mPX7yZ3286uijd4/3UuGOu6dY5Mt3j/cq4Y67p5nlPkn9LckK6Z2oGDbAtuT6f74+/bcBtJvt+la3Kpg8wf04BmJbOTfcX0p8POb/x2bGTt9s92rnNy+QD7Av9+TMGnNs13Zj9ZZLnjjv+rQz/r7Kz89TLk0bBB9I93qvGHXNNt85H0j3e5eOOuaab7vB07zva+GdySQYPsC25Pmv647MH3OaY/tw3t+RO78RWJbkn3fvpLko3bk/M4Pdz+XMKwLS08eU07xty/o/78+/cbvdo5zYvkw+wje+5OWrI+Vv684ePO3Zff2zYe+0e6s8/bzPvazW7Jrk53WMdG3fcNd087083Eq5K94/3luSfkrxk3Ne4pptm1yTfS/KjJHv0x5Zk8ADb3OuzZ556b+kg+/bn792C+70zW5XBH8DxkySvn/C1/pwCMC19OpN/otfG9498eLvdo53bvEw+wG7rzx865Pz1eeZ/nX28P7brkNuszfD/Sj6dbPwwgi9POO6abp5/ydP/Yfs3SV424Wtc001zSZJ/zdOvw5IM/v+Zm3t99ut/vWbI1+/Wn//F5t7pndxH07188GXpRtAr073P+N+SPJLuJbMb+XMKwLRkgG2eeTHAtoV3p3uMtyZ58YRzrumWeVmSN6d79mZdklePO+eaPrvXpPv0vSsmHF8SA2xb2PgfYL447pg/pwBMS16CuHnmxUsQp9rGj4z+53SfhDiRa7p1Dkz3j/hbxh1zTSe3a7rh+sM8/f1FiZcgbiuHpnu894875s8pANOSD+HYPPMy+QDzpvHNc2G6x3dzkpcO+RrXdOt9P91j3rf/tWs6uRdl8PuUBvXJ/jY+hGPrvDDd431s3DF/TgGYlnwM/eaZl8kHmI9N3nQfSvfYvp+nhsEgrunW2/iD1jf+rCnXdHJ7JLl6SP8rTw2jq5Oc3t/Gx9BvnbF0j/eH4475cwrAtOUHMW+6eZl8gO2V7iUwm/ODQ+dm9H5w6B+ke1zfyzPf8zWRa/rsDkv3DMJEM/LU+zivH3fcNd1ySzL4JYhbcn1G7QcxH57B/zHvoCQ/TnctLhp33J9TAKatQ/LUfyH/UpLLknyt//WPMvy19KPiTUn+R9//THdd7hh3bNmAr38i3bOHV6d7E//K/nbXJtllwO9xQX9+fZIV6T5CfHV/bOL3r25xusf1RLrHuWRAb51wG9d0chem+1lVX0n3wTqXJflsuj+nLd3PXTpiwm1c0y2zJIMHWLJl12d5nnpZ3FX97db3x86fwvu9M1iS7j1vX07yJ0kuT/JX6f7stv74cybcxp9TAKatA5L8Rbp/qD2e5K50723Ye7IbjYglmfw9IKsG3Oa4JNcl+Vm6f1zcnOS9GfzDRjc6Nd3LaTake9nnDenGynSzJM/+vpqvD7idazrcK9N9YM4P0v2j84kkD6Z7vEsy/FlG13TzLcnwAZZs2fV5a/91D/e3+0aSU7b+ru50Xp/kmnQD6ufp3r91X7r/cHB2Bo+pxJ9TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2Fn8/wV81yPwxVHPAAAAAElFTkSuQmCC\" width=\"432\">"
  27609. ],
  27610. "text/plain": [
  27611. "<IPython.core.display.HTML object>"
  27612. ]
  27613. },
  27614. "metadata": {},
  27615. "output_type": "display_data"
  27616. },
  27617. {
  27618. "name": "stdout",
  27619. "output_type": "stream",
  27620. "text": [
  27621. "-0.22013587 4.8883753\n",
  27622. "18554.22\n",
  27623. "(246, 213)\n",
  27624. "\n"
  27625. ]
  27626. },
  27627. {
  27628. "data": {
  27629. "application/javascript": [
  27630. "/* Put everything inside the global mpl namespace */\n",
  27631. "window.mpl = {};\n",
  27632. "\n",
  27633. "\n",
  27634. "mpl.get_websocket_type = function() {\n",
  27635. " if (typeof(WebSocket) !== 'undefined') {\n",
  27636. " return WebSocket;\n",
  27637. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  27638. " return MozWebSocket;\n",
  27639. " } else {\n",
  27640. " alert('Your browser does not have WebSocket support.' +\n",
  27641. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  27642. " 'Firefox 4 and 5 are also supported but you ' +\n",
  27643. " 'have to enable WebSockets in about:config.');\n",
  27644. " };\n",
  27645. "}\n",
  27646. "\n",
  27647. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  27648. " this.id = figure_id;\n",
  27649. "\n",
  27650. " this.ws = websocket;\n",
  27651. "\n",
  27652. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  27653. "\n",
  27654. " if (!this.supports_binary) {\n",
  27655. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  27656. " if (warnings) {\n",
  27657. " warnings.style.display = 'block';\n",
  27658. " warnings.textContent = (\n",
  27659. " \"This browser does not support binary websocket messages. \" +\n",
  27660. " \"Performance may be slow.\");\n",
  27661. " }\n",
  27662. " }\n",
  27663. "\n",
  27664. " this.imageObj = new Image();\n",
  27665. "\n",
  27666. " this.context = undefined;\n",
  27667. " this.message = undefined;\n",
  27668. " this.canvas = undefined;\n",
  27669. " this.rubberband_canvas = undefined;\n",
  27670. " this.rubberband_context = undefined;\n",
  27671. " this.format_dropdown = undefined;\n",
  27672. "\n",
  27673. " this.image_mode = 'full';\n",
  27674. "\n",
  27675. " this.root = $('<div/>');\n",
  27676. " this._root_extra_style(this.root)\n",
  27677. " this.root.attr('style', 'display: inline-block');\n",
  27678. "\n",
  27679. " $(parent_element).append(this.root);\n",
  27680. "\n",
  27681. " this._init_header(this);\n",
  27682. " this._init_canvas(this);\n",
  27683. " this._init_toolbar(this);\n",
  27684. "\n",
  27685. " var fig = this;\n",
  27686. "\n",
  27687. " this.waiting = false;\n",
  27688. "\n",
  27689. " this.ws.onopen = function () {\n",
  27690. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  27691. " fig.send_message(\"send_image_mode\", {});\n",
  27692. " if (mpl.ratio != 1) {\n",
  27693. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  27694. " }\n",
  27695. " fig.send_message(\"refresh\", {});\n",
  27696. " }\n",
  27697. "\n",
  27698. " this.imageObj.onload = function() {\n",
  27699. " if (fig.image_mode == 'full') {\n",
  27700. " // Full images could contain transparency (where diff images\n",
  27701. " // almost always do), so we need to clear the canvas so that\n",
  27702. " // there is no ghosting.\n",
  27703. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  27704. " }\n",
  27705. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  27706. " };\n",
  27707. "\n",
  27708. " this.imageObj.onunload = function() {\n",
  27709. " fig.ws.close();\n",
  27710. " }\n",
  27711. "\n",
  27712. " this.ws.onmessage = this._make_on_message_function(this);\n",
  27713. "\n",
  27714. " this.ondownload = ondownload;\n",
  27715. "}\n",
  27716. "\n",
  27717. "mpl.figure.prototype._init_header = function() {\n",
  27718. " var titlebar = $(\n",
  27719. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  27720. " 'ui-helper-clearfix\"/>');\n",
  27721. " var titletext = $(\n",
  27722. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  27723. " 'text-align: center; padding: 3px;\"/>');\n",
  27724. " titlebar.append(titletext)\n",
  27725. " this.root.append(titlebar);\n",
  27726. " this.header = titletext[0];\n",
  27727. "}\n",
  27728. "\n",
  27729. "\n",
  27730. "\n",
  27731. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  27732. "\n",
  27733. "}\n",
  27734. "\n",
  27735. "\n",
  27736. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  27737. "\n",
  27738. "}\n",
  27739. "\n",
  27740. "mpl.figure.prototype._init_canvas = function() {\n",
  27741. " var fig = this;\n",
  27742. "\n",
  27743. " var canvas_div = $('<div/>');\n",
  27744. "\n",
  27745. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  27746. "\n",
  27747. " function canvas_keyboard_event(event) {\n",
  27748. " return fig.key_event(event, event['data']);\n",
  27749. " }\n",
  27750. "\n",
  27751. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  27752. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  27753. " this.canvas_div = canvas_div\n",
  27754. " this._canvas_extra_style(canvas_div)\n",
  27755. " this.root.append(canvas_div);\n",
  27756. "\n",
  27757. " var canvas = $('<canvas/>');\n",
  27758. " canvas.addClass('mpl-canvas');\n",
  27759. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  27760. "\n",
  27761. " this.canvas = canvas[0];\n",
  27762. " this.context = canvas[0].getContext(\"2d\");\n",
  27763. "\n",
  27764. " var backingStore = this.context.backingStorePixelRatio ||\n",
  27765. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  27766. "\tthis.context.mozBackingStorePixelRatio ||\n",
  27767. "\tthis.context.msBackingStorePixelRatio ||\n",
  27768. "\tthis.context.oBackingStorePixelRatio ||\n",
  27769. "\tthis.context.backingStorePixelRatio || 1;\n",
  27770. "\n",
  27771. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  27772. "\n",
  27773. " var rubberband = $('<canvas/>');\n",
  27774. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  27775. "\n",
  27776. " var pass_mouse_events = true;\n",
  27777. "\n",
  27778. " canvas_div.resizable({\n",
  27779. " start: function(event, ui) {\n",
  27780. " pass_mouse_events = false;\n",
  27781. " },\n",
  27782. " resize: function(event, ui) {\n",
  27783. " fig.request_resize(ui.size.width, ui.size.height);\n",
  27784. " },\n",
  27785. " stop: function(event, ui) {\n",
  27786. " pass_mouse_events = true;\n",
  27787. " fig.request_resize(ui.size.width, ui.size.height);\n",
  27788. " },\n",
  27789. " });\n",
  27790. "\n",
  27791. " function mouse_event_fn(event) {\n",
  27792. " if (pass_mouse_events)\n",
  27793. " return fig.mouse_event(event, event['data']);\n",
  27794. " }\n",
  27795. "\n",
  27796. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  27797. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  27798. " // Throttle sequential mouse events to 1 every 20ms.\n",
  27799. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  27800. "\n",
  27801. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  27802. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  27803. "\n",
  27804. " canvas_div.on(\"wheel\", function (event) {\n",
  27805. " event = event.originalEvent;\n",
  27806. " event['data'] = 'scroll'\n",
  27807. " if (event.deltaY < 0) {\n",
  27808. " event.step = 1;\n",
  27809. " } else {\n",
  27810. " event.step = -1;\n",
  27811. " }\n",
  27812. " mouse_event_fn(event);\n",
  27813. " });\n",
  27814. "\n",
  27815. " canvas_div.append(canvas);\n",
  27816. " canvas_div.append(rubberband);\n",
  27817. "\n",
  27818. " this.rubberband = rubberband;\n",
  27819. " this.rubberband_canvas = rubberband[0];\n",
  27820. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  27821. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  27822. "\n",
  27823. " this._resize_canvas = function(width, height) {\n",
  27824. " // Keep the size of the canvas, canvas container, and rubber band\n",
  27825. " // canvas in synch.\n",
  27826. " canvas_div.css('width', width)\n",
  27827. " canvas_div.css('height', height)\n",
  27828. "\n",
  27829. " canvas.attr('width', width * mpl.ratio);\n",
  27830. " canvas.attr('height', height * mpl.ratio);\n",
  27831. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  27832. "\n",
  27833. " rubberband.attr('width', width);\n",
  27834. " rubberband.attr('height', height);\n",
  27835. " }\n",
  27836. "\n",
  27837. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  27838. " // upon first draw.\n",
  27839. " this._resize_canvas(600, 600);\n",
  27840. "\n",
  27841. " // Disable right mouse context menu.\n",
  27842. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  27843. " return false;\n",
  27844. " });\n",
  27845. "\n",
  27846. " function set_focus () {\n",
  27847. " canvas.focus();\n",
  27848. " canvas_div.focus();\n",
  27849. " }\n",
  27850. "\n",
  27851. " window.setTimeout(set_focus, 100);\n",
  27852. "}\n",
  27853. "\n",
  27854. "mpl.figure.prototype._init_toolbar = function() {\n",
  27855. " var fig = this;\n",
  27856. "\n",
  27857. " var nav_element = $('<div/>')\n",
  27858. " nav_element.attr('style', 'width: 100%');\n",
  27859. " this.root.append(nav_element);\n",
  27860. "\n",
  27861. " // Define a callback function for later on.\n",
  27862. " function toolbar_event(event) {\n",
  27863. " return fig.toolbar_button_onclick(event['data']);\n",
  27864. " }\n",
  27865. " function toolbar_mouse_event(event) {\n",
  27866. " return fig.toolbar_button_onmouseover(event['data']);\n",
  27867. " }\n",
  27868. "\n",
  27869. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  27870. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  27871. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  27872. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  27873. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  27874. "\n",
  27875. " if (!name) {\n",
  27876. " // put a spacer in here.\n",
  27877. " continue;\n",
  27878. " }\n",
  27879. " var button = $('<button/>');\n",
  27880. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  27881. " 'ui-button-icon-only');\n",
  27882. " button.attr('role', 'button');\n",
  27883. " button.attr('aria-disabled', 'false');\n",
  27884. " button.click(method_name, toolbar_event);\n",
  27885. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  27886. "\n",
  27887. " var icon_img = $('<span/>');\n",
  27888. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  27889. " icon_img.addClass(image);\n",
  27890. " icon_img.addClass('ui-corner-all');\n",
  27891. "\n",
  27892. " var tooltip_span = $('<span/>');\n",
  27893. " tooltip_span.addClass('ui-button-text');\n",
  27894. " tooltip_span.html(tooltip);\n",
  27895. "\n",
  27896. " button.append(icon_img);\n",
  27897. " button.append(tooltip_span);\n",
  27898. "\n",
  27899. " nav_element.append(button);\n",
  27900. " }\n",
  27901. "\n",
  27902. " var fmt_picker_span = $('<span/>');\n",
  27903. "\n",
  27904. " var fmt_picker = $('<select/>');\n",
  27905. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  27906. " fmt_picker_span.append(fmt_picker);\n",
  27907. " nav_element.append(fmt_picker_span);\n",
  27908. " this.format_dropdown = fmt_picker[0];\n",
  27909. "\n",
  27910. " for (var ind in mpl.extensions) {\n",
  27911. " var fmt = mpl.extensions[ind];\n",
  27912. " var option = $(\n",
  27913. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  27914. " fmt_picker.append(option)\n",
  27915. " }\n",
  27916. "\n",
  27917. " // Add hover states to the ui-buttons\n",
  27918. " $( \".ui-button\" ).hover(\n",
  27919. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  27920. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  27921. " );\n",
  27922. "\n",
  27923. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  27924. " nav_element.append(status_bar);\n",
  27925. " this.message = status_bar[0];\n",
  27926. "}\n",
  27927. "\n",
  27928. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  27929. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  27930. " // which will in turn request a refresh of the image.\n",
  27931. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  27932. "}\n",
  27933. "\n",
  27934. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  27935. " properties['type'] = type;\n",
  27936. " properties['figure_id'] = this.id;\n",
  27937. " this.ws.send(JSON.stringify(properties));\n",
  27938. "}\n",
  27939. "\n",
  27940. "mpl.figure.prototype.send_draw_message = function() {\n",
  27941. " if (!this.waiting) {\n",
  27942. " this.waiting = true;\n",
  27943. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  27944. " }\n",
  27945. "}\n",
  27946. "\n",
  27947. "\n",
  27948. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  27949. " var format_dropdown = fig.format_dropdown;\n",
  27950. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  27951. " fig.ondownload(fig, format);\n",
  27952. "}\n",
  27953. "\n",
  27954. "\n",
  27955. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  27956. " var size = msg['size'];\n",
  27957. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  27958. " fig._resize_canvas(size[0], size[1]);\n",
  27959. " fig.send_message(\"refresh\", {});\n",
  27960. " };\n",
  27961. "}\n",
  27962. "\n",
  27963. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  27964. " var x0 = msg['x0'] / mpl.ratio;\n",
  27965. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  27966. " var x1 = msg['x1'] / mpl.ratio;\n",
  27967. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  27968. " x0 = Math.floor(x0) + 0.5;\n",
  27969. " y0 = Math.floor(y0) + 0.5;\n",
  27970. " x1 = Math.floor(x1) + 0.5;\n",
  27971. " y1 = Math.floor(y1) + 0.5;\n",
  27972. " var min_x = Math.min(x0, x1);\n",
  27973. " var min_y = Math.min(y0, y1);\n",
  27974. " var width = Math.abs(x1 - x0);\n",
  27975. " var height = Math.abs(y1 - y0);\n",
  27976. "\n",
  27977. " fig.rubberband_context.clearRect(\n",
  27978. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  27979. "\n",
  27980. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  27981. "}\n",
  27982. "\n",
  27983. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  27984. " // Updates the figure title.\n",
  27985. " fig.header.textContent = msg['label'];\n",
  27986. "}\n",
  27987. "\n",
  27988. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  27989. " var cursor = msg['cursor'];\n",
  27990. " switch(cursor)\n",
  27991. " {\n",
  27992. " case 0:\n",
  27993. " cursor = 'pointer';\n",
  27994. " break;\n",
  27995. " case 1:\n",
  27996. " cursor = 'default';\n",
  27997. " break;\n",
  27998. " case 2:\n",
  27999. " cursor = 'crosshair';\n",
  28000. " break;\n",
  28001. " case 3:\n",
  28002. " cursor = 'move';\n",
  28003. " break;\n",
  28004. " }\n",
  28005. " fig.rubberband_canvas.style.cursor = cursor;\n",
  28006. "}\n",
  28007. "\n",
  28008. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  28009. " fig.message.textContent = msg['message'];\n",
  28010. "}\n",
  28011. "\n",
  28012. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  28013. " // Request the server to send over a new figure.\n",
  28014. " fig.send_draw_message();\n",
  28015. "}\n",
  28016. "\n",
  28017. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  28018. " fig.image_mode = msg['mode'];\n",
  28019. "}\n",
  28020. "\n",
  28021. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  28022. " // Called whenever the canvas gets updated.\n",
  28023. " this.send_message(\"ack\", {});\n",
  28024. "}\n",
  28025. "\n",
  28026. "// A function to construct a web socket function for onmessage handling.\n",
  28027. "// Called in the figure constructor.\n",
  28028. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  28029. " return function socket_on_message(evt) {\n",
  28030. " if (evt.data instanceof Blob) {\n",
  28031. " /* FIXME: We get \"Resource interpreted as Image but\n",
  28032. " * transferred with MIME type text/plain:\" errors on\n",
  28033. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  28034. " * to be part of the websocket stream */\n",
  28035. " evt.data.type = \"image/png\";\n",
  28036. "\n",
  28037. " /* Free the memory for the previous frames */\n",
  28038. " if (fig.imageObj.src) {\n",
  28039. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  28040. " fig.imageObj.src);\n",
  28041. " }\n",
  28042. "\n",
  28043. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  28044. " evt.data);\n",
  28045. " fig.updated_canvas_event();\n",
  28046. " fig.waiting = false;\n",
  28047. " return;\n",
  28048. " }\n",
  28049. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  28050. " fig.imageObj.src = evt.data;\n",
  28051. " fig.updated_canvas_event();\n",
  28052. " fig.waiting = false;\n",
  28053. " return;\n",
  28054. " }\n",
  28055. "\n",
  28056. " var msg = JSON.parse(evt.data);\n",
  28057. " var msg_type = msg['type'];\n",
  28058. "\n",
  28059. " // Call the \"handle_{type}\" callback, which takes\n",
  28060. " // the figure and JSON message as its only arguments.\n",
  28061. " try {\n",
  28062. " var callback = fig[\"handle_\" + msg_type];\n",
  28063. " } catch (e) {\n",
  28064. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  28065. " return;\n",
  28066. " }\n",
  28067. "\n",
  28068. " if (callback) {\n",
  28069. " try {\n",
  28070. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  28071. " callback(fig, msg);\n",
  28072. " } catch (e) {\n",
  28073. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  28074. " }\n",
  28075. " }\n",
  28076. " };\n",
  28077. "}\n",
  28078. "\n",
  28079. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  28080. "mpl.findpos = function(e) {\n",
  28081. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  28082. " var targ;\n",
  28083. " if (!e)\n",
  28084. " e = window.event;\n",
  28085. " if (e.target)\n",
  28086. " targ = e.target;\n",
  28087. " else if (e.srcElement)\n",
  28088. " targ = e.srcElement;\n",
  28089. " if (targ.nodeType == 3) // defeat Safari bug\n",
  28090. " targ = targ.parentNode;\n",
  28091. "\n",
  28092. " // jQuery normalizes the pageX and pageY\n",
  28093. " // pageX,Y are the mouse positions relative to the document\n",
  28094. " // offset() returns the position of the element relative to the document\n",
  28095. " var x = e.pageX - $(targ).offset().left;\n",
  28096. " var y = e.pageY - $(targ).offset().top;\n",
  28097. "\n",
  28098. " return {\"x\": x, \"y\": y};\n",
  28099. "};\n",
  28100. "\n",
  28101. "/*\n",
  28102. " * return a copy of an object with only non-object keys\n",
  28103. " * we need this to avoid circular references\n",
  28104. " * http://stackoverflow.com/a/24161582/3208463\n",
  28105. " */\n",
  28106. "function simpleKeys (original) {\n",
  28107. " return Object.keys(original).reduce(function (obj, key) {\n",
  28108. " if (typeof original[key] !== 'object')\n",
  28109. " obj[key] = original[key]\n",
  28110. " return obj;\n",
  28111. " }, {});\n",
  28112. "}\n",
  28113. "\n",
  28114. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  28115. " var canvas_pos = mpl.findpos(event)\n",
  28116. "\n",
  28117. " if (name === 'button_press')\n",
  28118. " {\n",
  28119. " this.canvas.focus();\n",
  28120. " this.canvas_div.focus();\n",
  28121. " }\n",
  28122. "\n",
  28123. " var x = canvas_pos.x * mpl.ratio;\n",
  28124. " var y = canvas_pos.y * mpl.ratio;\n",
  28125. "\n",
  28126. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  28127. " step: event.step,\n",
  28128. " guiEvent: simpleKeys(event)});\n",
  28129. "\n",
  28130. " /* This prevents the web browser from automatically changing to\n",
  28131. " * the text insertion cursor when the button is pressed. We want\n",
  28132. " * to control all of the cursor setting manually through the\n",
  28133. " * 'cursor' event from matplotlib */\n",
  28134. " event.preventDefault();\n",
  28135. " return false;\n",
  28136. "}\n",
  28137. "\n",
  28138. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  28139. " // Handle any extra behaviour associated with a key event\n",
  28140. "}\n",
  28141. "\n",
  28142. "mpl.figure.prototype.key_event = function(event, name) {\n",
  28143. "\n",
  28144. " // Prevent repeat events\n",
  28145. " if (name == 'key_press')\n",
  28146. " {\n",
  28147. " if (event.which === this._key)\n",
  28148. " return;\n",
  28149. " else\n",
  28150. " this._key = event.which;\n",
  28151. " }\n",
  28152. " if (name == 'key_release')\n",
  28153. " this._key = null;\n",
  28154. "\n",
  28155. " var value = '';\n",
  28156. " if (event.ctrlKey && event.which != 17)\n",
  28157. " value += \"ctrl+\";\n",
  28158. " if (event.altKey && event.which != 18)\n",
  28159. " value += \"alt+\";\n",
  28160. " if (event.shiftKey && event.which != 16)\n",
  28161. " value += \"shift+\";\n",
  28162. "\n",
  28163. " value += 'k';\n",
  28164. " value += event.which.toString();\n",
  28165. "\n",
  28166. " this._key_event_extra(event, name);\n",
  28167. "\n",
  28168. " this.send_message(name, {key: value,\n",
  28169. " guiEvent: simpleKeys(event)});\n",
  28170. " return false;\n",
  28171. "}\n",
  28172. "\n",
  28173. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  28174. " if (name == 'download') {\n",
  28175. " this.handle_save(this, null);\n",
  28176. " } else {\n",
  28177. " this.send_message(\"toolbar_button\", {name: name});\n",
  28178. " }\n",
  28179. "};\n",
  28180. "\n",
  28181. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  28182. " this.message.textContent = tooltip;\n",
  28183. "};\n",
  28184. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  28185. "\n",
  28186. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  28187. "\n",
  28188. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  28189. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  28190. " // object with the appropriate methods. Currently this is a non binary\n",
  28191. " // socket, so there is still some room for performance tuning.\n",
  28192. " var ws = {};\n",
  28193. "\n",
  28194. " ws.close = function() {\n",
  28195. " comm.close()\n",
  28196. " };\n",
  28197. " ws.send = function(m) {\n",
  28198. " //console.log('sending', m);\n",
  28199. " comm.send(m);\n",
  28200. " };\n",
  28201. " // Register the callback with on_msg.\n",
  28202. " comm.on_msg(function(msg) {\n",
  28203. " //console.log('receiving', msg['content']['data'], msg);\n",
  28204. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  28205. " ws.onmessage(msg['content']['data'])\n",
  28206. " });\n",
  28207. " return ws;\n",
  28208. "}\n",
  28209. "\n",
  28210. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  28211. " // This is the function which gets called when the mpl process\n",
  28212. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  28213. "\n",
  28214. " var id = msg.content.data.id;\n",
  28215. " // Get hold of the div created by the display call when the Comm\n",
  28216. " // socket was opened in Python.\n",
  28217. " var element = $(\"#\" + id);\n",
  28218. " var ws_proxy = comm_websocket_adapter(comm)\n",
  28219. "\n",
  28220. " function ondownload(figure, format) {\n",
  28221. " window.open(figure.imageObj.src);\n",
  28222. " }\n",
  28223. "\n",
  28224. " var fig = new mpl.figure(id, ws_proxy,\n",
  28225. " ondownload,\n",
  28226. " element.get(0));\n",
  28227. "\n",
  28228. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  28229. " // web socket which is closed, not our websocket->open comm proxy.\n",
  28230. " ws_proxy.onopen();\n",
  28231. "\n",
  28232. " fig.parent_element = element.get(0);\n",
  28233. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  28234. " if (!fig.cell_info) {\n",
  28235. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  28236. " return;\n",
  28237. " }\n",
  28238. "\n",
  28239. " var output_index = fig.cell_info[2]\n",
  28240. " var cell = fig.cell_info[0];\n",
  28241. "\n",
  28242. "};\n",
  28243. "\n",
  28244. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  28245. " var width = fig.canvas.width/mpl.ratio\n",
  28246. " fig.root.unbind('remove')\n",
  28247. "\n",
  28248. " // Update the output cell to use the data from the current canvas.\n",
  28249. " fig.push_to_output();\n",
  28250. " var dataURL = fig.canvas.toDataURL();\n",
  28251. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  28252. " // the notebook keyboard shortcuts fail.\n",
  28253. " IPython.keyboard_manager.enable()\n",
  28254. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  28255. " fig.close_ws(fig, msg);\n",
  28256. "}\n",
  28257. "\n",
  28258. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  28259. " fig.send_message('closing', msg);\n",
  28260. " // fig.ws.close()\n",
  28261. "}\n",
  28262. "\n",
  28263. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  28264. " // Turn the data on the canvas into data in the output cell.\n",
  28265. " var width = this.canvas.width/mpl.ratio\n",
  28266. " var dataURL = this.canvas.toDataURL();\n",
  28267. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  28268. "}\n",
  28269. "\n",
  28270. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  28271. " // Tell IPython that the notebook contents must change.\n",
  28272. " IPython.notebook.set_dirty(true);\n",
  28273. " this.send_message(\"ack\", {});\n",
  28274. " var fig = this;\n",
  28275. " // Wait a second, then push the new image to the DOM so\n",
  28276. " // that it is saved nicely (might be nice to debounce this).\n",
  28277. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  28278. "}\n",
  28279. "\n",
  28280. "mpl.figure.prototype._init_toolbar = function() {\n",
  28281. " var fig = this;\n",
  28282. "\n",
  28283. " var nav_element = $('<div/>')\n",
  28284. " nav_element.attr('style', 'width: 100%');\n",
  28285. " this.root.append(nav_element);\n",
  28286. "\n",
  28287. " // Define a callback function for later on.\n",
  28288. " function toolbar_event(event) {\n",
  28289. " return fig.toolbar_button_onclick(event['data']);\n",
  28290. " }\n",
  28291. " function toolbar_mouse_event(event) {\n",
  28292. " return fig.toolbar_button_onmouseover(event['data']);\n",
  28293. " }\n",
  28294. "\n",
  28295. " for(var toolbar_ind in mpl.toolbar_items){\n",
  28296. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  28297. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  28298. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  28299. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  28300. "\n",
  28301. " if (!name) { continue; };\n",
  28302. "\n",
  28303. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  28304. " button.click(method_name, toolbar_event);\n",
  28305. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  28306. " nav_element.append(button);\n",
  28307. " }\n",
  28308. "\n",
  28309. " // Add the status bar.\n",
  28310. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  28311. " nav_element.append(status_bar);\n",
  28312. " this.message = status_bar[0];\n",
  28313. "\n",
  28314. " // Add the close button to the window.\n",
  28315. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  28316. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  28317. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  28318. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  28319. " buttongrp.append(button);\n",
  28320. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  28321. " titlebar.prepend(buttongrp);\n",
  28322. "}\n",
  28323. "\n",
  28324. "mpl.figure.prototype._root_extra_style = function(el){\n",
  28325. " var fig = this\n",
  28326. " el.on(\"remove\", function(){\n",
  28327. "\tfig.close_ws(fig, {});\n",
  28328. " });\n",
  28329. "}\n",
  28330. "\n",
  28331. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  28332. " // this is important to make the div 'focusable\n",
  28333. " el.attr('tabindex', 0)\n",
  28334. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  28335. " // off when our div gets focus\n",
  28336. "\n",
  28337. " // location in version 3\n",
  28338. " if (IPython.notebook.keyboard_manager) {\n",
  28339. " IPython.notebook.keyboard_manager.register_events(el);\n",
  28340. " }\n",
  28341. " else {\n",
  28342. " // location in version 2\n",
  28343. " IPython.keyboard_manager.register_events(el);\n",
  28344. " }\n",
  28345. "\n",
  28346. "}\n",
  28347. "\n",
  28348. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  28349. " var manager = IPython.notebook.keyboard_manager;\n",
  28350. " if (!manager)\n",
  28351. " manager = IPython.keyboard_manager;\n",
  28352. "\n",
  28353. " // Check for shift+enter\n",
  28354. " if (event.shiftKey && event.which == 13) {\n",
  28355. " this.canvas_div.blur();\n",
  28356. " event.shiftKey = false;\n",
  28357. " // Send a \"J\" for go to next cell\n",
  28358. " event.which = 74;\n",
  28359. " event.keyCode = 74;\n",
  28360. " manager.command_mode();\n",
  28361. " manager.handle_keydown(event);\n",
  28362. " }\n",
  28363. "}\n",
  28364. "\n",
  28365. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  28366. " fig.ondownload(fig, null);\n",
  28367. "}\n",
  28368. "\n",
  28369. "\n",
  28370. "mpl.find_output_cell = function(html_output) {\n",
  28371. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  28372. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  28373. " // IPython event is triggered only after the cells have been serialised, which for\n",
  28374. " // our purposes (turning an active figure into a static one), is too late.\n",
  28375. " var cells = IPython.notebook.get_cells();\n",
  28376. " var ncells = cells.length;\n",
  28377. " for (var i=0; i<ncells; i++) {\n",
  28378. " var cell = cells[i];\n",
  28379. " if (cell.cell_type === 'code'){\n",
  28380. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  28381. " var data = cell.output_area.outputs[j];\n",
  28382. " if (data.data) {\n",
  28383. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  28384. " data = data.data;\n",
  28385. " }\n",
  28386. " if (data['text/html'] == html_output) {\n",
  28387. " return [cell, data, j];\n",
  28388. " }\n",
  28389. " }\n",
  28390. " }\n",
  28391. " }\n",
  28392. "}\n",
  28393. "\n",
  28394. "// Register the function which deals with the matplotlib target/channel.\n",
  28395. "// The kernel may be null if the page has been refreshed.\n",
  28396. "if (IPython.notebook.kernel != null) {\n",
  28397. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  28398. "}\n"
  28399. ],
  28400. "text/plain": [
  28401. "<IPython.core.display.Javascript object>"
  28402. ]
  28403. },
  28404. "metadata": {},
  28405. "output_type": "display_data"
  28406. },
  28407. {
  28408. "data": {
  28409. "text/html": [
  28410. "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA2AAAAJACAYAAADrSQUmAAAgAElEQVR4nOy9eZBdWX7Xeex2N91UjSpetaSQFFKWltZS2lK5K1fl9vI+lRakklRaS1LqlVIlKUu7SkuptEu5vrQx3TRNYBvHGDBjGMAzmIEBBjPYEQ7jgMAmbAweFg8QgA3DYIfBeOI3f5x77j333HPfy6pSKXWlzyfiG1X18u3vvu77eb/f+R2lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4BmyVCn1o0qpf6OU+m9KqX+hlPohpVRhDp8TAAAAAADAS8cqpdS/U0qJUuovK6XGlVJ/O/zvX1NKfXPunhoAAAAAAMDLxV9XWrY+ci6fCS//E8/9GQEAAAAAALyErFJasv65Uur7nb/9D0qp31FK/a5S6rXn/LwAAAAAAABeOj5QWsC+l/F3Ux0beG7PCAAAAAAA4CVlSmnBuprx92+Hfz/7Oe//nyulflsp9UuEEEJITvPbSv//GQAAwBfmTyotWB9k/P1J+PdbNe4n6/+0/uD71Vdk3le+SQghhOQy36++IkpLGAAAwBfmyxaw3533lW9KUCgTQgghucy8r3xTwv9PAwAA+MJ82S2Iv4SAEUIIyXMQMAAAeJZ82UM4EDBCCCG5DgIGAADPki97DD0CRgghJNdBwAAA4FnzZW7EjIARQgjJdRAwAAB41qxSSv07pWXrLyulxpRSfzv873+ilPrmF7hvBIwQQkiug4ABAMCXwTKl1I8ppf6tUur3lVL/Uin1Q0qpwhe8XwSMEEJIroOAAQBAnkDACCGE5DoIGAAA5AkEjBBCSK6DgAEAQJ5AwAghhOQ6CBgAAOQJBIwQQkiug4ABAECeQMAIIYTkOggYAADkCQSMEEJIroOAAQBAnkDACCGE5DoIGAAA5AkEjBBCSK6DgAEAQJ5AwAghhOQ6CBgAAOQJBIwQQkiug4ABAECeQMAIIYTkOggYAADkCQSMEEJIroOAAQBAnkDACCGE5DoIGAAA5AkEjBBCSK6DgAEAQJ5AwAghhOQ6CBgAAOQJBIwQQkiug4ABAECeQMAIIYTkOggYAADkCQSMEEJIroOAAQBAnkDACCGE5DoIGAAA5AkEjBBCSK6DgAEAQJ5AwAghhOQ6CBgAAOQJBIwQQkiug4ABAECeQMAIIYTkOggYAADkCQSMEEJIroOAAQBAnkDACCGE5DoIGAAA5AkEjBBCSK6DgAEAQJ5AwAghhOQ6CBgAAOQJBIwQQkiug4ABAECeQMAIIYTkOggYAADkCQSMEEJIroOAAQBAnkDACCGE5DoIGAAA5AkEjBBCSK6DgAEAQJ5AwAghhOQ6CBgAAOQJBIwQQkiug4ABAECeQMAIIYTkOggYAADkCQSMEEJIroOAAQBAnkDACCGE5DoIGAAA5AkEjBBCSK6DgAEAQJ5AwAghhOQ6CBgAAOQJBIwQQkiug4ABAECeQMAIIYTkOggYAADkCQSMEEJIroOAAQBAnkDACCGE5DoIGAAA5AkEjBBCSK6DgAEAQJ5AwAghhOQ6CBgAAOQJBIwQQkiug4ABAECeQMAIIYTkOggYAADkCQSMEEJIroOAAQBAnkDACCGE5DoIGAAA5AkEjBBCSK6DgAEAQJ5AwAghhOQ6CBgAAOQJBIwQQkiug4ABAECeQMAIIYTkOggYAADkCQSMEEJIroOAAQBAnkDACCGE5DoIGAAA5AkEjBBCSK6DgAEAQJ5AwAghhOQ6CBgAAOQJBIwQQkiug4ABAECeQMAIIYTkOggYAADkCQSMEEJIroOAAQBAnkDACCGE5DoIGAAA5AkEjBBCSK6DgAEAQJ5AwAghhOQ6CBgAAOQJBIwQQkiug4ABAECeQMAIIYTkOggYAADkCQSMEEJIroOAAQBAnkDACCGE5DoIGAAA5AkEjBBCSK6DgAEAQJ5AwAghhOQ6CBgAAOQJBIwQQkiug4ABAECeQMAIIYTkOggYAMCrw36l1B9TSv2fSqn/VyklSqmfqHGbDqXUzyil/qNS6veUUv9IKXVJKfWVKrfZqZT6O0qp/6yU+h2l1C8opU58gedtg4ARQgjJdRAwAIBXh3+otHT9F6XUr6raAvZHlFJ/oLRE/YhSakop9Wvh7X4q4zaj4d9/Syn1HaXUDyqlfjO8bPoLvwIEjBBCSM6DgAEAvDr0KaVWK6W+TynVq6oL2Dyl1L9XSv03pVSzdfnXlVI/H972kHOb5Uqp/6qU+u3w3w0FpdQ/C2/T/vmfvlIKASOEEJLzIGAAAK8mvaq6gJ0K//7jnr/1h3/7Wefyh+HlDz7j/X0WEDBCCCG5DgIGAPBq0quqC9hPhH8/7PnbDyilflcp9d+VUn/Iuvzvqewq1+Lwb7/5+Z5uBAJGCCEk10HAAABeTXpVdQH7xfDvTRl//5Xw729bl/2H8LJvZtzmd8K//+FZPL9fysjvImCEEELyHAQMAODVpFdVF7BfD//+rYy//5xKV7t+P7zsBzJu86/Dvy+exfNDwAghhLyUQcAAAF5NetWLLWBZ0IJICCEk10HAAABeTXrVi92CmAUCRgghJNdBwAAAXk16FUM4CCGEkOceBAwA4NWkVzGGnhBCCHnuQcAAAF5NelXtjZj/g/psGzGvUGzETAghhFQNAgYA8OqwRyn1p8P8b0oL0W9Yl017rv8HSq/d+lNKqUml1K+Ft/sppdT3eR7jo/Dvv6WU+o5S6geVbjsUz/1/HhAwQgghuQ4CBgDw6nBfaRHKyr/w3KZTKfUzSqn/pJT6PaXULyulLiulvlLlcXYp3Z74X5ReK/aLSqkTz+D5K4WAEUIIyXkQMAAAyBMIGCGEkFwHAQMAgDyBgBFCCMl1EDAAAMgTCBghhJBcBwEDAIA8gYARQgjJdRAwAADIEwgYIYSQXAcBAwCAPIGAEUIIyXUQMAAAyBMIGCGEkFwHAQMAgDyBgBFCCMl1EDAAAMgTCBghhJBcBwEDAIA8gYARQgjJdRAwAADIEwgYIYSQXAcBAwCAPIGAEUIIyXUQMAAAyBMIGCGEkFwHAQMAgDyBgBFCCMl1EDAAAMgTCBghhJBcBwEDAIA8gYARQgjJdRAwAADIEwgYIYSQXAcBAwCAPIGAEUIIyXUQMAAAyBMIGCGEkFwHAQMAgDyBgBFCCMl1EDAAAMgTCBghhJBcBwEDAIA8gYARQgjJdRAwAADIEwgYIYSQXAcBAwCAPIGAkc+dtsPT0nokzNFpaTk2Lc3HK9J00spwRTafn5F1t2dky5mKtByzbnMkefvWo/7LW96flsZyRTZempG3b83M+esmhLxYQcAAACBPIGBkVvFKky1eJ7RsRQnla8uHFVl7Z0ZWP6pI/bmKtLyvb9d22B/7b61HtNBtOVOR9R/PyKrxitR9d1KW/+C0rJysyLceV2TN/RlZcx8pI+RVDgIGAAB5AgEjqbhCVFO8Tiblq+V9XbVqGq7I5lEtX996WpFNF2ak6WQlUelqOzwtbYf8MtZybFoaRiqy/vqMrBqryFvfnpK6Pz0mdd+blOU/NC2rxmIBW1GZlrf+2JS89cenpO57k1L3vck5fx8JIc8nCBgAAOQJBIxE8VWjvNLlthmerEjzibC6dTS+bvOJimz+aEZWP5yRbz2tyNs3Z2TLhxVpPh5LWCRgnkTVrxu6+vXWd6ZkxZ97LHU/Oi7L/+i0fOupFrC1n2pBW/6D01L33clIwOq+i4QR8ioEAQMAgDyBgL3iiYTncLoaZYtXJF1Om2EkXY5QtRyblqaTev3X2zdnZM2DGVl/Y0Y2fzQjjafCtWDmNlUErOEDXTlb90nYgvinJrSITVdk1XhFVj+qyNq7oYD90VDAvjspy//otKyc0pW3uX6PCSFfbhAwAADIEwjYKxhbcrYejGOLT9NwRRpPVaSxrP/ZNKwrVwlxqlIlaxrW8tTwQUUaTutKVv05vSas4XTcqth61FMFC++35f1Y/BrL+rbrr89EefumHu6x9lNdYVsxrSXsrR8O2xG/PSUrJyqyYmZa3vr2lLz1nSlZ/kPTsuGqrsRFrylsmZzrz4UQ8vmCgAEAQJ5AwF6R+CpMW9+b0gnlywy9aCzH8tR4Kqx0WeJlp+VYLErNJ+I0nQwFzop9n6YNse1wKIDOc2k7nG55bDylJcyk/pxucdx0YUY2Xp6RDddCKftkRr71pKLXiU1UZOVERUvZt6eiIR6rxnTlbP2NGdl4KZ7QaF4PQkZIfoKAAQBAnkDAXoGkxMsWnvemdMtgOOo9kqRyuLbLrnodjcfCGykyFaTm41Y16Zh+jPYDU9K5dzJK+4FYsLYenJaOfVPStXtSekrjsq04FqWnNC7d70zo2+zXt7HbIG3JM2ks68paw4iutm0enZH1H+sBHWsezMi3Hld0m+IPTUvdn5iUuj85IXU/Oi51PzIub317Sr71JBZDuypmhonM9WdICMkOAgYAAHkCAXvJ4203tKpNrUf0Wq2GD7S4NHwQD9QwMhVVuUyFK5SU5hMVaTtkidT2CekdGJP+nidSbLwnQ5vuSLDhtgTrb0mw/pYM1d+RYuM9Kbbcl2LrAyk235OhhrsSrLspwZqPJVh9XWfNxxKsvyXF5nsy0PlI+vqeSs/2CencoyXOzdb3pqKJjG4FbsuZitSf1UK24eqMrLk3I2/98LQe0vFj4zrfm5S3fnhaNl2cidoS7bjVvObjr66QJaqUvmRsL2Bnrl8DefmCgAEAQJ5AwF7SZErXe7G0RO2GI3HlywzWSLUWHo+rYVvf05Wtnu0TMtj+UIYa7mrJWn1dSiuuSGnZRQnmj0jw5unk83rztL58wRkJFp3TWXhWX2ZnwRkJFp6V0pJRKdVdktKqaxJsuC1DDXdloPOR9Pc8kb6+p9I7MCbbAl0taz8wFbVE2s/Zfg0NH2gRW/eJnsy4ajxcN/ZD07KiMi0bL+kBIQnJ9AnYiUriPTUiONefuZvUfmvO8dB+YEra98fp2Bfm3TD70n+zpdcbd02hPdzFWeNnBzEjXyQIGAAA5AkE7CWL22borRgdDPfYOh227X2QHCVvtxQaiWnfPyU92yd0dav1gQzV35Fg7Q0pLb0QS1ShLMEbp2Ro3rAMvXY8zusnkpk3LEPzhiV441Qy5nW8eTqOkbKFZ6W0+LyUll6Q0rKLUlpxRYI1H8vQpjtSbH0g3TsmpH3/VLSOzR7ykVirdkKvH9s8OiObLuqq2Nu3ZmTtnRnZfL5KBawcp2m4oteuOVJri8pcHgN2u2hqz7UsETuQfg2JeKQsygHPZfvjY80nZb695cx6wLn+DpH8BQEDAIA8gYC9JEmJl1212B+36ZlhGI3lWLjc1r22w9PStWtS+nufSLH5nq5uLTqXliwTW66MdH3jmI4RMPv6joAl/tv3+uzrhfdd/PrR+P7nDUuw+roMtj2Q7ncmorbKtsPT0foz+30w69hSLZZmvZsz0bHlfX1/ZpLj5lGrUmb2P3PG6Zs1cB37dLUwIS9O+6QZ228mRpoR/24lzk3i+R+znq9zmW94ik9+3EqVTywjEQsTvb/vJiXNjS1ls21VNM9jrr9b5MUPAgYAAHkCAct57GpGdNLstI21HdKSZYZsmCqOK14t7+v7GOh8JMH6W7r9b/F5CRacScqVW9FyYwTMkS9XuMxl0b+b1+VWxuzbhPJlYh4nmD8ipeWXZajhbtSeaKp1g+0Pdeti7xPZVhyTjndj+Yna6Q56NoY+HFfPmk/otWSbLs7IxiszUn82XDM3EuZ0cuy+PUEyIUBWZcqIRjS2PxwiYm7nrrdzhcwVsKzMRsAy2xVrSJg9ZMWOK2OpyljWWjKPiJnnMdffNfLiBgEDAIA8gYDlOO4+Xnb1yz7ZbTxVidoNo329rAmCLe/r25k1XaWlFySYP5KscNkthbVEzP67p90wVQ0Lr+dex3t9S8AiyQsfK3jjlAQLzsRtiktGdXukWU+2/LIEa2/IYNsDGeh6LP29T6R3IJy6uHMiub7JklozgXHLhxXZeFnvQbbpom5ZtBNNYPxIj7bfeEX/s/6sNTrf/PuZ+LMwn48Zre9bh+YKWKqC54t1ndR+a7OsQGVK2L4aErZnMlH581bFDmSsG/M9v0NIGMkOAgYAAHkCActp3HHyvuEIZrx8VJEpJ4dJROJVGpfBtgd6TdeS0Vh6XKHyCZivDTFrrVehnC1gGW2Krpwl5Cvj8RL3aVohrRbH0tILUlp+WQ/3WH9LhrZ8KoNtD/QI/O0T0rUr2bZoJKzppBaojZdnZPNHM1J/rpKIqYBt/kivLdtwTf+z/lwsXvVnKwkhs8Vs83l9v2YSpTvi3zci39tueNQRMLPhtU/Ys8QnY2CHK2AJ4dozKV27w+wKs9uRMTdWa2hNCTsct3bO9fePvFhBwAAAIE8gYDlMavPi95LriaK2tpPOhsrDcZpPVKKKV7DuphavN0+nBcZX7XIFzHc9n3yFUxFduaoqUXZ1641TyXVf5j1xhdF6nilhc9ebzR+RYNE5KdVdiiYtDrY/1NWxQS1kZj+ytsPxXmS28NgVptYjep3d5lG9OfTGS/FgD3sioxmRn9hUelRfv2HEGojiiFQqVdZ62RMhW96P5cUdluFbm+a7jlnPZoTLiFb3jgnp2T4hPaVxvadbEKenNC492yeke8eEdO+c8AvZLCTMXafWvh8JI3EQMAAAyBMIWM5it2P5RoCbKYDRxsQfxBUvs3Hy1oPT0r1jQoINt+OR8b7KlCNBKWGq1qJor+sy0wzNZENbmHwVNHOZW22z7jsolLOHglj3mWpX9FX1jOAtOqerYyuu6P3IwurYQNdj6et/qlsVjUjsiqs9rky4gz58lae2w7G8mRH59WcrsunCjDScTm+AnTlcw7O+K5LwcBNpM9Sj/UBYtQrlqXvnhHS/E4tTT2lcegfHpK/vqfT3PNHp1SP/+/qeSn/vk/jynifS3/1Y+rsfy0DXYxlse6D3dmu5L8Xmezot9+P1d92Po7V53e/E75/dpmgfx7VaJamEETsIGAAA5AkELCdxBxL4qgWtR+JJena7YcsxPQ2wv/eJDNXf0YKx6Fx25cgnV+HlwRun4v293jjlr4w5whYUysnq12wHejgDN9zJhymJ801YtNsQze0yBnn4RuNHl715Ol5LtuKKHn/ffE+vJzObRZfG0y14uybTVaOwCtS1K5SgUOg690xGLY8++TDS0blX366nNB6LkZPuHXpNm2lbbD8wpYeStNzXA1ZWXtVr/RadS479N1VQp8oZvSfhlgCJfdzc/15wJinc1t5vpSWjeqPtjZ9IsfGerjb26Gpj557JWMSqbfbsxKx7nOvvKJm7IGAAAJAnELAXPL5BBGZ/JfsktPVIWEk5nWw5bD5RkW3BuBSb70lp5dXohDtz7Zav2mWfiBfK0cl15gh6V6x8FTX3ep41Zq58RbJUY7x9QpreOJWcyjhvuKrUpYaF+Cpl4cTFqEq26Y4Mtj2Qvr6nUYUs+mfYdte1a1K635mQbcG49PXrCtNA12MZbH+oJzW2xdMatwW60mZXiDr36Nv3DozJQOcjMZtfl+oupbP8sgxt+TQSse4dE9LX91SCNR9r6VpwJinf5j21knq/Tcx74B6r9mV2RdI5DiKJM22fq69rGWu5L9uKY9K9cyIxpTK1objbooiEkQICBgAA+QIBe8HjG8dtn5jaAyKi9V7hmPmWY9PSuWdSn6gvGZWgUPZLl0/AfGvBrJPvVJWkmoD52hd97YUZElBNBrIELBpx7z6WI2DuJMWqsmhdp7T4fDzIY93NSMISa54sGesdGJOBjkcytOVTPexk5VUprbiihWnphXhyY90lLXX1d6TYeC8ao19svidDm+5oiTLbA7x5OvN9Dhae1cK94bbO6utJaXb2a/O9v973vNbnm7WG0L2P10/oY9xMrVx1TYot96W/50lUSYwmJTpTPrMmJ249OD3nm2CTuQkCBgAAeQIBe4HjnUhnn3SG64iahtPy1XZ4WnpK41JsvBdXPDIqTZkn8YVy8nbO+qxIYrLubzYTE+3rVBMv3wbP1iCOzLVrntskKjyvHfduCD0rAau7FE9SrCJgfX1PZajhbtz6aVo4Pc89qhAtOBO19pWWjMYbYbtr6HzvoS0480fiimXW5++pgGWm2kRMn8x7PlNvRW3BGS2MGz/R1cR+XU3s3DuZud7RJ2FmgMhcf3fJ8w0CBgAAeQIBe0Fj79kU/fLvk6+T4Xqvcrx/VPuBKd1ytuG2lJaMZstEVlXDHqDhCpizPis13MJtXXSqVQnZma2A+U747bVlWdMb7fv72pH4ufokzl7vVXDWqnkqPKVlF7UwhPJVbH0g/b1PEhP/TPVraMunumVxwZn4vrOqRa+fSAlh5nAU972uJUQ+QcrK5xUwV4BrCZgtjG+e1mK76poM1d/R7Zhm4+z9/q0W3MEd5jvCgI5XKwgYAADkCQTsBUtWxcudDNd0spKYcNd8XFe9hhru6jY23xqtjOpEzRNr38RC39qoQtm/dqpahaSKgFV9XlmPm1WB+dqROFlry7KExjOco7TsYjQh0axdikas74mHbGwLxqMR/7WkypXA1JCTam2WWQLs+SxTguf7TOzjwnec+I4b32dc7TOtJnnzhvVau6UXpNhyP1ERi4TMHZ3vrI20Nyaf6+81+XKDgAEAQJ5AwF6g+AYOJAYNHLTWfBnxCvd4aj8wJb0DY/FaL1/Vytci6DuR9lQnag3SSEwd9AmcT8rsljnfY1dpU0xUTmYhYaYKlhKw8L8zH++1uEUx+qzeOKXFoPGe9A6ORRMM3XTt1gIWLDqnP5Ma8hUJmHVM2K/HVxnLFDDf+1tNwD5rBewzCJhXdGs9TnjfwRundPVw4yfRgJKu3ZOJ/cPs+NoTt76HgL3sQcAAACBPIGAvUFLyZa0BswduNJ+I5av1qB4xP9D1WI/3zpIgXzUk62TaV7HIErCstrOsv2WdeM9WwHzSNm84HnlecAaNVHtNpkLjVvocofAK2LKLUmy8FwmBES5XwHpK4/HI/yqVrJSMhY9lVx8zWxN9VTKfrM7zTHl0PzPfZ5Qlzu7n5BF1V3wTAuaRLl+rYrRH26prMtRwV/p7nyT3XnM3c0bCXrkgYAAAkCcQsBckqf2NDoeb6loCZjZZbj6hWw5bj0xL165JGWx/qNcjzR/Jbv2r1srnkaHMDYx91Rbfmq/P8nhZcdrYMp/HvOHk3lO27LjCGd5vUCjr25jYm1H72vnsxyqUJVh3Uwa6HutNhXdPZqb7nQkpLb3gbwf1CVGGhKWqfPb7nrVGzH6vzWvOkq8sAcuSeI/cRc/TEmGvgH0G+Uo8/zdP6wrvupux+O6NY4+vR8JerSBgAACQJxCwFyCuePnkq+3wtLQciwWs7dC0dO+YkGLLfd2i5Zty52tJqyFDZuhFYgBGLfn6rBI2WwFzr29Xo+yphYVyvAFwoZwWMKclMaqoLL8cj3S3b+tWltwq0oIzMtj2ILH2K1PAdk7oEfAZrYKp48Fcb541ZMT8zTcFsdagDmdNVVDwbIZd6/PytbFmtKkmpjgWyvGxFEpYrc/clS/f3m/B/BHd/jlgtX8aCdvnlzC7jXeuv+/k2QcBAwCAPIGAzXGqypdT/Wo5Ni0t7+t/biuO6el6yy5KUCgnT459sjRL+fGNCc9a9+WVgFrVNt/J+2zaEo04FcrJgRiFsh5hvmQ0LVEZ70nw5ulYwJZdTI+Gr1IhCuaPSGnVNekdHJPud8KNlndlC1jXrkm9FcCic9kC9ubpeFz8/JHosRNtj2+e9lbqMteFeV5/sPBs1b3AMj+vLMH2VStNO2j4XN11YLMS7VmIeWnpBQk2fqI3m945EUmYEbBIwjLWUs7195482yBgAACQJxCwOYy9ybK36hWKV+tRnbbDemPlga7HEiw4U112bCnKOsl2L7MFxVRbCnErWeZ92EKWtTbJJ4Jua5vvxNxu0yuUU9MIo/fTrhzZUpIhgKlBHF89lBQJ570MFp6VYM3HMtj+ULYF48mNlu0q2C4n4TqwYusDXal845RXZCMpXDKqpXDh2eQeXrXWfFUTMNN+GN5n6j4+awXM0zKYale1RaxQzj4OXJl3q2pZYmZVI4PV12Ww/aH0bJ+I14MdSG9Y7mauv//k2QUBAwCAPIGAzVHsilci7jqwo7rilZCv1dez2w1tabAlxK1U2Ldz7idYcEbvc7X0QrSJc1b1IjVa3D3J9p14+06ys4TQWSeVFd+6qpSAfcOZhmjy1UM61mu02y9Li89LsP5WNIUvsc/XTk8VzBGw7p0Tsq04pttF6y7FEuYIRaI1ctlF/biLzkmw8GxKqDI/Q4/0RuuyasmQT458n6lPYj3HQVAoR8+/6oAU37HhtlFWEf9g/oiUVl6VYuuDZBviwfiHjdYj6e8WEvbyBAEDAIA8gYDNQRITDq2kxs8fjk8cO/dMSn93OOnQrVbEy3wAACAASURBVH75Kk2ugPlOdjMqEpGAGQkwwz0yBGy2e3b5pKNq26JT4UlJl3sy775u++TdFgZXwDL2CDMn90P1d/ybLGcJ2O7JlJB17/BImOf9NBMWEzFDPKqJUpbU2oMx3AElWcmSrwwBy6ygmQqVWZ9nP36148McF+5nWEUQjYRtC8alc++ktB+Yilt3349bd6MfOQ5TCXuZgoABAECeQMDmIN7ql7VxrC1gWw+G8tXzRIK1N7R8Za3J8rWmVRO1jLU9wRunJFh4Nq7A+ATMORHPXNeTVeEIT6hTkuiKhKey5ZUvcyLu7EfmW3tUbT8wc93gjVN6XdnaG9I7EK/3soWrqoDtjsfSm2pY944J6R0ck2LzPb2Rs09qXw9bQBeejdoRo421s2Qp6323Bczd3Nn9bLKOF7fFMUvAfDJojiV3fVs1UXc/d/f4qnKb4M3TemuA4ph07p2UrQfDwTXhtg1NJ/Weeb5W37n+3wTyxYKAAQBAnkDAnnNS8lVj8+XOPZPS1/dUgvW3aq/7yqoQZJ1M+6oM9vqaQjmenBfKzKwHJ9QSMEsOUm2SbsXD11roa3WsdX++qp37WkwL5sqrMtRwV/q7H1evejnthl4BcyphvQNjejBHtVZE0zIYiliw8Kz+HLKEKEtg7OphoRwLmP267ffWOn68I/Id0UoJmPseGym217LVEClXvrJaHH23Ly27KENbPpW+/qfStXtS2g5pAWsshzkVbuFwlMEcL1MQMAAAyBMI2HNMov3JrXo5E9u2HpyW9gNT0tf/VIKNn8RT9KpVO5wWsVQ1yZWYWtPtnAqV90S4loDZIuC2xoXvS7XHd9sPM4d7uBKRtW7IJ5qm2rT0gpSWX5ahTXdkoOOR9A6M6bZDT8XLlbCgUE4LmactsXvnRCRhpaUXvEM5EgJmsvBsvJbKNyrfV9l02zcLZf9QFl+76usn4mPXN1WxRkU0cayY+woFLCW/vqqndbxl7knnEeuhecNaWDfclv6eJ9K1e1Jaj0xLw+mkhDWdrESDbZCw/AcBAwCAPIGAPaf42g3NuOzEvkXvTUn7/inp3DMpvYNjuv2sUK4uEb42Mo9IVa0g+SpDbhUq6/HdZIhY9BxsubD3L8sSxkLZ//w9ghGtdTIpeKTDEg8zznyw/aH0lMZ1q+GOZGyhcuXL/Zy91TGfhO2ckL7+p3orASNitkwWyvEkRPP6rapY9N75BNUn1752z6zqonn8rGPF/ZwdKUpIky3c4WeSeayF18v8vOxKrkf2bEkL3jgVDU/p734sTScr0nC6EolYwwfhf39QkaZh3ZrIYI78BgEDAIA8gYA9h7hth5F87Q8TCpi5rHNvPLrcu8FyloBlyZJ94uqu8fFULjKrWJ6qQ2brY8b1gkI5KWAFpwKWJVYmTgUoJQ3hOPdo7ZrnZH3oG8e0fJnphmG1yx0tb/+3T8B8n7W3NdETc/99fU9lqP6Ortr4JMyu6hmJWXg2ni4Yvv5Ei2G19VwZ679sYY3eR3fT56wWV/dy+732CVjW8WZ/9u7xa0t5oex/Hm4lsVCOqmEd+6akabgiDSNawJqGtYBtOaMva/hAb3BuqmJz/b8Z5LMFAQMAgDyBgH3J8e0/FMmWs1ls+4Ep6Xh3SrrfmZCBjkf+cfO+6kNWG2K1k2TPfVUVMF+roitnnvtNtY/ZomRO8M19Wu1wicER80fiTYjN/mQZFbFIUMyaKU+lJBqwseF2JF+Jvb3ceASs2mfulS2PmHXvnJDudyakv/eJBBs/8UuYK2CFsn4vwj3DzDYBiQpgwTPu3a2Q+gTMfn89e8F5P2ff559VAQ2fX6YU+56j+zzN+1yt2ufIWmnJqPT3PpGt703pytdI3IpoJGzLGf3vTScr0Q8lc/2/HWT2QcAAACBPIGBfcuzhGlGsdkP78o59Wr76ux9LsO6m3v+p2q/8sxGyWi2C1eJpH0wNYvBVx5y2Rm9roXmP7MEPrnyFlbLS0gvxIApLwLxS4Kv0fCM5LKJUd0mPlu95ItuKY9JTGtfth1UErFbly81sBMz8rWd7+JlvuC2lxef9wmFiZHThWf2+1F2K14aZv4VS5l0X5hGm6L125dZ+XPv+3Pfatz7MV5GyJyKG4l1VwJznnnhOWQLmvl7zHm64LX19T2XrwelIwpqGw0pY+N9GwqJx9UhYboKAAQBAnkDAvuSYaldCujwDN7YenJbunRN63PzGT3R7nGdAQ7VqU00Jy1rLNRuZc9cFVauuhZPuvPLlkQt3TVd0om0kY9U1vTnx4vPZe0nVei1mLdyCM1JsuS99/U+lZ/tEIpFsZQjYZ/3sXdFKrAmz/7ZjQnpK4zLQ+UiLd/ieJITDXtdmS9iKK/q9WTIqpcXn9T+XjCY/qyryNfTa8eT9V9vUOqsqlTUcxXfd+SOJyp2RMNMW6u71Zl5H1cEx9mftHmdhTMWzr/+ptB2Oh3IYCWssxxLWeCo5rn6u/zeE1A4CBgAAeQIB+5LSvl+3E3a8OyUd+/TarsQeX4eSUxA73p2SoYa7Ulp+ObnnkytB9jQ7p9JUc7rcLCsGXplx1gqlKl5Otcb7+G5FxKwFM21p4XMJ3jilL199XW88vfq6PoE264fctsJwDy9vBW+e3gy4tOKKDG35VPp7niQHbViVrc49k9K5N86zOhZc4fKtJ7PbEUsrrybWd1UbihFVCRefl1LdJSmtuCLBmo+1rBbScutrS4yulyXs9m2yWv6y2hgdcYqGY3heX0IgzRo3s47PFbrPWskNjysjYr0DY1q4PkyL2JYPYxFjTVg+goABAECeQMC+pHS8q4dpRAJ2YCq1ybJZD9axb0p6SuP6xNveaNknYIVy5jqazBHxnopFau2UfVnWcI2wghGdFJv7N5WNxefjwRrVKmT2Cbu9Xss8j/kjUlp2UYINt7VMLLuoH9OzzsgIWJZ8lZZekGDdTRlsexBVveyNk410dbybrFQ+y2MhS8DsypiRsG3BuJ6MaETcHTbiCpE19S9YdE4L2Ppb+p+2vLxujZV32wztiqJTMXRj7sM9/hJthp7HSVS37D3BzDEdHj/RdgCm5dSdkjkLAfNOV3QlbOMn0npkWq//+jCehtg0XIkvGwkHcxxBwF70IGAAAJAnELAvIUa+OvdMJqpfUeXLnoa4f0q6d4RDN0xVIKtVzFpDYypQmeO8s9ry3PVcbgXM3M5dS2VXpmwBe+24BG+e1ifOyy6mWyft+/G1IC46pys3Rt4WnNHrmjbclqEtn+oqmBE0VwDsKpzz+oOCHr5QbLyn13oF4Yj5sNLV8a7zuRyelpb3db6MY6KahCWqYe9M6FZEeyhHlTbCqPpnpHbROSmtuqYrh4vORe9b9N4Z0THvt1mPlSVgTvUqGsrx2vG0+LuDW3xruFzps4+F+SO6rdJUyOwfGmoJmKcy6m1JfT2ejtg7OCatR2MJayzrIRyN5bSEUQV7sYOAAQBAnkDAnnE69sXy1bln0tt6aNaWbH1vSrp2TUZDN6quo3EF7LXj2Se/7hoo5+Q1MVmv2m3c6lehHFe4zInx6yfitVrh2iO30uWbvJdY57XyaryWacUVCTZ+IoNtD2So4a7+bzNkIhQ9M2I+KJTT65PMCfbSCxKsvyW9g2PS/Y6uMhnxMtLVenRamo9brWdnKl/qsVGrEhaNpu9/KoNtD7REuRVRW2rs9VPWMVJafF5XDpdeSAhWVF0Mq0zRUBP3PXQqm4kULPn62pHs9k9P5TVRac04xlOSnXWfvnZJuyJXq/21UJahTXdkWzAuLcem9Sj6kVjCGj7Qx0P9Wf3vrAd7sYOAAQBAnkDAnmE69k3FAhYmte7Lqn517pmUvr6nEk2/y2rbc0+Irb2UvCeaWSe3RqRcAXPlzXcybUmTXZWIqmJuu5hd/aomYPNHdJVr3U0JNn4iQ/V3ZLD9YTyMxFTVwr29Sksv6H8P144FhXJqXzB7f6/uHRO61XCvrkZuPTgtLcemE5WO+nMV2Tw681yOEZ+EuWvBtgXj0t/7RLxrAmexbisolLXMLr0Qv092G6CzmXPiPbQ+P1ONLC2/HL3nxa8fleJXD+k4AuatiHnaGL3Cb4uTXeFz1/gZqc+6X5+AuVW08PLS0gsytOVT6dk+oSXsdDgd8WQsYfVndSUsmozIRs0vZBAwAADIEwjYM0z7fi1g9vANV7zMSVzHvinpHRyLNuFNDb/IWjdltyBmiU7WCa/TUlattcs+mU5sqOvEXvMTtQT62g99bZCFsq5qrbomQ5vuSLHlvgx0PpL+nid6b6w1H8fT/UzbnJEva4+qoFCOBSwUusH2h7KtOBbJV/v+WL4aPtAn1ZtHZ2TThRnZeOn5yFdQKMfrzvZ4piGGAtazfUJ6B8dkoOtx1IqYEmh7YqFnzaB533yS5Y5z9+6p9voJ3Qq67qYE627qSmShHMuXETBLdrxrET3Hobdt9hvHvG2D3krbLATMlrnEsWn9PXjjlJSWXZRi4z3pfieWsKaTuu0w2qz5Q31Z6xEE7EUNAgYAAHkCAXtGad8/FQtYOHQjJV5hunZPykDnIz10w1rP5V3T4pOWQtl/4mxLlV3pypCnrPZDV76qDTXwnjybNjJfm6O75iwclDFUf0cG2x7IQNdjGWx/KMHGT+IWOVu27D2r3H2rFpyRYO0NPekwrHxtfW9KWo9MS/OJuKKx8fKMbLwyIxuuPj/xclNVwnZoCdtWjCUsKJSTsuFOtLTXxIXVK1e+UlMVC8lWUjfBupsy0PVYP4e1N7Kfg/0ZVzuGLanyVV1TFTATR6oS0u+89kjYQkEc+sax+Hk7ApZYw7jiihRb7kv3jglpPFWJU64kKmNI2IsZBAwAAPIEAvaMYsQrmnh4MC1e5uStr/+prizY63uyWv9cAXOmF3rHixsBC59b5n3XGGCQOWTBU81ICZhZLzQLAQsWnpVg7Q0Z2vKpFJvv6ZbMZRcTFS672pMQsPBvQaGsqxnN92RbMK7XfO2dlNYjut2w4XRFNp+fkU0X51a87GRK2A49jGNbMC59fU+l2HJfb8rtDE1Jybd5r817agTWvEf2EAzfvl9OSquuyVDDXRlquKt/LChYkyrtfcnsbQRmKfiZApbVumq3wprnXygn3xNbwKzhJNFxWO27teCMlFZdk2LrA2k+XklJmJmUSCviixkEDAAA8gQC9owSjZ3f55cvk/YD4X5fZlpg1sh5S6S8o8irVBhSAuapUGQO73BawjJbynztXvYJbaHsHZDhq9wE80f0OqO1NyRYe0O3vrmtc7ZcGAGzHiOYP6KrX71P9KTDvZPSfmAqlq9R3Wr4oshXUChHw1q6diclzK6C9Q6O6WppKKSJYRbmvty9tsx4f7d6aOJUEL0CNm842YK47GKyhdHeFNp6DO+6tIzjy3u5r23Rvq45rquM5U+1IDrbNvieV/DGKf2erb4unXsnUxLWMKKPIzOW3mwhMdfHENFBwAAAXg2+qZT6QCn1l5RS/0wp9XtKqf+slPp7SqmyUur7M27XoZT6GaXUfwxv84+UUpeUUl+p8lg7lVJ/J7z/31FK/YJS6sQXfQEhCNgziBm8EU3Yc9Z72YM3undOaNmoUnlItIFlDUmoVs0yFZLw+fluV3PvsKz7taoNiUELVSpcCXmyx5DbArZkVA+OWH45OXjDHkdu3g/P8I3SsotSbLkvPaXxaPpk22G93mvz6IxsvPxiyVdQKEeDWrwCFkqYGchhb66cqGS576U93MSpUgWFsvcyt7IWDTNZdlFPqFx5VQ/0MO2s9kh5txpW8FQ9fZL1GZKQKTMIJkvm3ON23nBcac56DPv7svCsDHQ9lo53p6IJmU3Duvpl9gpDwF68IGAAAK8GHyqlRCn1b5RSf0YpNaaU+lGl1P8TXv4XlFLf59zmjyil/kBpifoRpdSUUurXwuv/VMbjjIZ//y2l1HeUUj+olPrN8LLpZ/A6ELBnkEjAwqEbZmR1NIAjTOfeSb2eplD2nwR6qhD2Oif3V/5MUTInk26bmStg7nQ598Q5a92XezJdbQCIfX3POraEgC27qGNEzIynNyPTzfCNQjndxrj+lvT1PZWuXfHn0PL+tGw+H8rXtRdLvkwSVTCPgJm1YEP1d6KJiL61f+6aQPP+etsOMyTWrbaWll6IP4slo1WrZfYxl6g2mWNkFmvDalbNrMea9Q8I4fHlrZb5vnvzhqN1hO0HpqJhHI2ntIA1nqpI69FQwA7ShviiBAEDAHg16FdK7VLpStcipdS/UlqQ9lmXz1NK/Xul1H9TSjVbl39dKfXz4fUPOfe1XCn1X5VSvx3+u6GgdNVNlFLtn/8lKKUQsC8ce+ph+4GpeK1XuM+XGUHffmBKthXHJFh/y18h8J0Y2u1W1eTLuZ9ovzAziKFQTp0U2wJmb+SbqhTUaFNM3C5LxNxKgyMQwfwRPWI+3J8qkjBTfVl2Md5nzB51b1UuBtsfSveOiagK2Xp0WpqGK7rt8NoLLmCOhNkCZiSs2BruCxZuSp14/3zDWDxCFRTKs5KvqKq4ZFSPoa+7FI3/9w7esI9XuwpWq5L6WQXM+gGgmoAlLp9njeyfjYC9dlxXXsM95NoO6QEuTSe1fDUNsw7sRQwCBgAAt5WWoz9mXXYqvOzHPdfvD//2s87lD8PLH3huU+3+PgsI2BeIvd+XqXy1HnUE7D0tZ/29T/QgA99UQvPLvrvmxTl5zZxM6BMw57kmxCprnddrx9PXzRCvzOmI7lo196TXJ2rmxN1ukzNri4xEujJp3a608qp07QrbDg/pUfONp/TQjQ1XX1z5io6jPRkCZklYX99TPaBk9XUtYW7Fy/eeO/9dTdS8raELz0YyHKz5WK8FsyXYcxxELYmFclq+wueQ2UqbVcXyXCf1PTCvJaMd17cOMlMGw1bX0sqr0t/9WDr2aaFvORbHVMBoQ3wxgoABAMB1peXoB63LfiK87LDn+j+glPpdpdR/V0r9Ievyv6eyq1yLw7/95hd8rgjYF4iRr4534xO01qM6RsDa909Jz/YJGaq/o9eiZFW/3OqT5+Qzczx8lV/zI+mpsnYsIWDm5PnzCFjWejHnufg2/bXXrAWFcnLIg2k9NO2HtjQsPCtDm+7E674OTUvzcb3B8os08bDmsVRNwnbGwziCjZ/oalSh7BcqT2ugu7bL274Y3p99H2Yj5mDtDSm2PpDBtgdaAE0lzLeWMBS36Fi35atQTrYD1pKtKgKWOgbNa5xNZdluacyqxM0b1q9z0x3ZFownf2CxWhBpQ3wxgoABALza/IBS6peVlqPAuvwXw8uaMm73K+Hf37Yu+w/hZd/MuM3vhH//w7N4Xr+Ukd9FwD5fzAmzaXlreV+vOTISZk7QOvdORlPsol/orVaqVBvfbKoAjjT5qh2JVkV3LVZW1cEImKfNL7Wux759tRNl+7HNSXihnGyrdFsTzXXsSpg7zc8aPT/Y/lALWNgC2jRcidd+5VTAXAnbFoxLf88TKTbe05XUBWeyK1qegRqJ99bdP80MtnAEJlhwRu+P1XhPBjofyUDHI10JW3ROX99tMzSfcVitTMhcoawvD6t3roT5NnSuKmHWdVPfqVptjPax6buuXV1dflkG2x/G7cTWQJ0oVMHmPAgYAMCrzbTSUvRXnct/Pbz8Wxm3+zmVrnb9fnjZD2Tc5l+Hf188i+eFgD3jmMpX+wFd/Wo+UZHm4xVpeV8LmDkx6ymNS7Dhtpaaar/K+9oQq5x8pibDmRNx56S2+PWjtQXKbr0qlOPNoR05Sjw/35CNGpWwoFBOthLWEgV3aIQ7Tn3BGQnW3ZS+vqeJtV8NH1Rk0wW92fJcHyef6ZiqImA9pXHp63+q14Ktu5mYiJi5Bs+39stu67Sl1h3WYgRs+WUJ1t+SYvM9GWq4q6tvofx514PZLbD2GjX7s884VmdT9aoq/rNdV5ZV+XKrtqaat+F2dHzZ0mX/91wfO696EDAAgFeXC0oL0a8qpd50/jbXApYFLYifI/bQDbPRb9Ow3iPIFbCBrsdSqruUHkaRMXRjVgLmVM6iE+ssAcsQJd/+XmaAh++kOrVmaDbredyT2UXndOwKiStf1UTMfA7zR6S09IIUm+9JT2lcTz48rEV4y4eVF27Pr9nEHUefELF39DTEga7HMrTl08RERO+ACfOeulXEBWf0wJPF5+O9wqz3NVG1Wng2noS44ope/2Wvw7PF3FdB8n2W1m296x5rtQpWk7JqLYW+HztqyJdpiy0tvyzdOyakff9ULF7vpYVsro+fVzkIGADAq4kZF/+PlZ6E6DLXLYhZIGCfMe0H4r2+mk4m9wdqPhFLmBk7X6q75D3Z87Z9ZZ2Y1hKb8LlltnXZQva1I8m4bYrm/nwn1k57VqJq4qt62RJgV13cFjj7PbarI24FxxKIYM3HMtj2QLYF49K1a1K2HtRrvxpGdPUrb/JlEklYtY2Zux7rtWBLRjPXf0XvebiPWuK9XnhW37aWCNvtqNY6rqHXjqdbYH3HpzlOXEm0hck+3nw/UtjfC1ewfBWwrOtWqzbbt/NUEoM3Tkmx5b50vxNLWPuBqeh/C0zm+th5lYOAAQC8elxSWoR+WSm1MOM6DOF4SbL1vXjQQ8NpfcLf8IEeU21XwrYenJae7RPpdj5HmqKpiO4JpDkBrNbWZ/1Kn7XXV0LAfOLlaRVMVLgyWrXMCbp5jqmBCPbrNPIUPs+sykjVAREm80d09Wb9LenveSLd70xI1+7JSIi3fJiv4Ru+ZG7M/E7Yitj3VIYa7sZy75toaFcNzedofybunmr25+qsC7MrqeYzn/U0Tt/Ie0/La1Aop2XK933Iki+rIpwpYPax7gqrb5iJ/TzX3pC+vqfSuXcyki8k7MUJAgYA8GpxQ2kR+gdKqflVrscY+pckWw9OR+uMtnyop+01luN9gsy/d+zT7YfRCad7sme11CUqDBnruRInuB45qVo1Cy9Pbb7skyu3muCrOthtiW674zeOJU74vc+xVtuhdTLsrZKF63J6B8aka5eeRNl6RA/fqD+n2w/n+jj5InFbEF0J6x0ciyYSeuWrUM4eTe+T7CqtoF4Bm5cxAdHXghg+l0TLotuWGu5tlpA56z5SQpRVGfaIlffY9a2V821abqW07KIUWx9I9850FSySMNaCzVkQMACAV4dPlZagv6/Sa75c5indUvhZNmJeodiI+YWL2Zi1/lxFNo/OSMOIrno1DWsZ23JGD+PofmdCgo2fZK4rSazNKZTTwlJDwBJtYoVyWpasE1m7TTBxMm23GbpVs6y1N7UGIYSvz60spE5sM072U1WvLAHb+IluP9wdbgNwRO/99dIL2A5dBevvfizBhtvp981+r2vFN/zElSVbwF47njhmMgXMXR+WIYFBoazbIBeejapq7nEbHduzXddVTcCyrjdv2PtdTFTAFpzRmzMPjMUDOcJtJhCwuQ8CBgDwanBCaQH6A6X3+7rvyUnnNnvC6/+OUupPKaUmlVK/Ft7PTymlvs/zOB+Ff/8tpdR3wsf6zfCy6WfwOhCwz5jWI9PSMKLla/P5GWks65bDxrIefV5/riKtR6alvzscvuE58UttNGy35xXKSamqccIZXS/rpNOuOriiVK2a4baUZQ0FyWoD84hWqj2tSgtitIbJnXxYKOv9mRruSs/2CT2Nct+U3ny5HI+fn+vj5IvEJ2DuQI6+ft2GmBonX0u+fBUz8z7bwuR8bomJmpaUJ9aCOdWvzB8FzHFhhrIUymn5N9cxx6h77M+mojdLAQsK5XRLpkcWS3WXZLD9oXTtnkTAXrAgYAAArwb3lZagavk7ntt1KqV+Rin1n5RSv6f0urHLSqmvVHmsXUq3J/4XpdeK/aLSAvgsQMA+Q9oPTEnjqYps/mhGNo/OyJYzut3QDH/Y/JEWsM69kxJtvOxpkfIKmCsaWUMwqg0TcIcXuO1WvrUyzol0ahz4ZxGwWpUJW77s1+ru72UEzEzps/9WKEtp6QUZbH8o3Tsn9DTK/ZaAjeZbvoKCM4jDNxVxh94XrNj6IJp+mdmq57a+mvfbTjiMIyVg4fMx1amEaLnHjPsjgyuDblW2UI7aDxP37xxPQcFpr60hX6nvj/vdcAW0UI6/h+56OfcxwsprT2ncP4yDkfRzFgQMAADyBAI2y5i1Xxsvz8imi7r10Ew8bD6uBz9sHp2Rre9NyVDD3ejE0q0SRHJhtTyZk75UG5hnLUriZNInR9WuV+P27kmwd22Pr9KW9fi+SoJ9kmzvTeVUYBLtZ/YJ8/wRCdbfkm3FsWgj7Pb9eiPshg8qc36cPKvY8tW9c8JbCevre6qnGZotCLLWezlVqVT10a64+ipgTpuqndRec752SPd52de1fhiIhM6sUzQ/FMymndJ+nYWyv6XQfY72dE53oqfvGJ43LKXF56XYfE+6d04wDfEFCgIGAAB5AgGbRdoOTUvbYb3GaOMVLVqNp7R8tbyvhz+s/3hG6s9WZFtxTEqrrklQsKbLmV/z3cqPK1q+NqpqFTDfifBsBMzXmlWtyuVrfTSCVE3wnNcTFMrpSp+9v5czECJxkh7eV2nxeSk23pPudyYSAtZ8vPJSCVhQKHurX127YjHbVhzT+4GFo+ZdwajZemhLmFP9mq2AmaSGqPg+W19boOcYTu1PV03qfT8AvJ6cwFj1ddvDN9zX6RGwYP6IBOtuyrbiWCReroTN9XHzKgYBAwCAPIGAzSJth7VomQEPduth8wndfrjx0oy0HZ6WYst9KS0+721/ylyjY59gWnKTNZEt0QJmjZVPtIJlSVa1v82ynTA6gZ0/ki2Kr1sjxk2VwbS62RJmnaBXa/+KBGzFFenvfhxNP7QrYI3ll0vAOvf4WxBNdaz7nQkJ1nwcV8EKng2SM0Q2JcbOAA7vjwFVWlVTPy7MH0m2kPqGyniqaZnrD2fxI4S33dc34MXzWt21bV4BC7/DVp4NFAAAIABJREFUpeWXpb/7cTSMo/2AsxYMCXvuQcAAACBPIGA10nZ4Wk/YK4dthud19av5hBawpuF4TVjPdn1CHO2P5RMJ99d/9yTS/vXetJb57utZCZivmpB1fU8FIbMtcd6wBAvOSGnpBQlWX5dg3U0J1t6QUt2laL2RLZo11zCZx95wO9F+2LHPWgN26uUTsJSEWWvDundOSLD+ln6PF5xJvJdewcgQkMTjemTF/lyy9pJLtPMtOielJaN6vzb7GHYELrPl1bf+0Fe9nc16xGrilXX8Zz2e+WFh0TkpNt/TG4DbAmZJ2FwfO69aEDAAAMgTCFiNRNWvs7rKZdZ+2dWvTRdnpOX9aRlsfyilZRdrT6KzKljeFkJ7fYpdQbBPprNOPN1f86sJmNuallVlsH79906389x38MYpXZlZ87EUm+9Jf+8T6R0Yk2LrAymtvBqv+7Jb56pVIMKT6GLLfeneEU8/tAVsro+VZ53OvZaAWTFi1r1Tb3VQWnbRK2Cp6YieilCiNdQzCdFtZ0wJf3jMlZZdlNLyy3GWXtACZsvX145I8auHErf3fgd8axDdipZZq1VLwqzj0Vvtsu57Vq26r+u90IL1t6SnNJ4WsFDC5vrYedWCgAEAQJ5AwKrEVL+ahiuy6cKMbLwUVr+OW9Wv0RnZcHUmqkYEC88mBaVGm5O3GmBkZ8EZfRK76FxyVL19MlmrzTGjmpQphlmtiVknpO5JrN0uuPSCFBvv6b2TwlHxW9+bkr7+pxKsvRG9Lq/Qhe9D4sT7zdPS3/NEOvdMJk54O/ZNSevRl0/AgkJSwox4RZWxXZMytOXTeB2YdXz41htmVceigRW1BOy14ynxCuaPSGnZRRna8qkEG25LadU1LWCLz8eVYHO7rx6Swa8cTAtc1vfAVNcK5bi6Zlotq1XAahybibVeVpUsU8Lcy+YNS2nFFenrfxpvxrw/mbk+bl61IGAAAJAnELAqaT0SV7/MiPmmkzoNH2j52nRRrwkLNn6iKz4Fa2y2vZ7LrjD4WgTNmimzJiocw15adlFn6YWorSuSsnATW7OfUtTyVShnrudJnIRXEyq3BaxGhSH1GPNHtIC1PpCOd6ciid10YUa2fFiRtsNhxXDphfj24fvutsZF973gjHTvmEi0Hnbsm4o2Yp7r4+XLiP0aO96dSgnYYNsDPfQlFLDE523fV9aQjUI5XpsXXs87UMMck4vOSWnFFQk2fiLF1gcy2P5QBjofyVD9HV3ZdH4sSAhcWAXLXMNljoM3T+vjfPllLerrbmqxq7uk79/eG6zaMZlV6fVVv5x1ct7vhvUYwfwRGdryaUq8ELC5CQIGAAB5AgGrktYjel1R/TmdhtNavhrLFak/q4Vi8/kZaT0yrU8+7b2UnLa9REuhLWWm+mA2pbXFyqylMQnlKxIwI1/Wde1KSDUByzwhzZCxzD3CrBPY1OtaeFZKq65Jf/dj2frelF4r95Fu42w9Oi29g2N6fZi5nV2JsV+DEdSFZ6V750Q0fMPOXB8rX2aiDX/3hxJmVcUGuh7H1cRCOfPzriZgrrhHj20+x0Xn9I8Aq65p8Wq5r8Wr45EMtj2QoYa7cRuk1Voa3Z87YdBdD2mkJjwGSovPS6nukv5OrbupB41YVTXz/Kq2rVZb++a0ynq/s/bx53mMoFCWYO2NxI8BCNjcBQEDAIA8gYBVScuxadlyRle6tnyoxcvIlxm80TRckZ7SuD45LJSTbUxuFcze8NWWLkuiUhJmb5hrnpv93+a+FpyJr2+f8Ga1YGWs8UmdHDsC5luXk3qN9v5eloQ1Dev3r/lERTr2TUnvwJgEG277JXT+SOoEvbRkVLfi7Z2MJMRMopvrY+XLTNshvcGvETFTCevaPSn9vU909XXphfj4qyZgbsXS/swK5eQAGDNQo+6SBKuvy1D9HRlseyCDbQ+k2PpAhurvSLD6elT5TRybvjVl1oAW8/iJarF5LovO6YpvWPm1q2pudTQ1XdGzXiwhldZjZr03ie+VGSLia0NcfjmxFULUjsgasOceBAwAAPIEApaR1iPT0nwilK3zumrTWK5oITOVnNMV6dw7KcXGexIUHPmyTtQSJ4G2OBlpcqsP1nqXxOCBDFmKnrdpzZplVSBLwFIClzV+3D6ZNq8pPOlOvOb5I1Jaflm2BeNR+9y24pgUm+/pqZHmRNdU/MJWs8SwkteOS2n5Zenanax+bT04LQ0jL9f0w9SxeFTvQ9d2KJawzr1awHoHxqTYeE+3BdobMs+i8pmoztqxtg4oLT6v73vDbSk235Ohhrt68uKKK1qMjJzYlSPrBwLfMZZ4THPcu7e1bp+qXr12PC1VGWshU++nVQFLXOY+P3v7BN9G1/OGpbT0QnQ8tu/XPwS0HdKf01wfM69aEDAAAMgTCFhGzPCNqP1wJFz3dX4mbj08Oi39PU+ktOJKeoCEr0Lk/OKfkiXPyal3jYrvZDN83p9bwNwKgFtZcNsQ3Sqfee8yKgxBoSzB+lt63VDYthasvaErHOb1mjVvyy9Lqe5SPLwhXDdUWnUtGsDRdki3h264OiNrHszM+fHyZab5uG7ZbD0SS1jHPi1h24JxGeh4pNdJ2VVYtwpUKCcrXeFnlah4LTwbS4fJwrNaildelaFN1jqvN04ltkLwHYup9Y7mu2CPrHclLKNlMbrcc5mv4uuVL/u9cVsNnTVjkYSZOMf20LxhXZHdpadxbn1vSg/tOTr90g6EeZGDgAEAQJ5AwDxpPaJPohpO64rXljN6/VfDiK6INYxUpPXItPT3PtHrYgoZ+2FlLeb3VJWKXz+aOGn2DgvIWm9lxbumK6MlLWtQg/fxs4Yc+K7vaQEbmjcct5aZtWrh8y1+9VCc8GQ+KFgVxddPSKnukvR3P5b6sxVZe2dG3vrOlKz9i/dlw1/5VFb82Sdzfsx8mWks64mbzScq0nJMi9jWg9PSvn9KunZNSu+gHu8frL6u31cjFI74Z7UlZrYimuPLSIipylpibJIYomFLkW8kfKEcV9cWn4+rwPZxZAu/e5++SYVVjj3zOlK3rTaEJuMHlMR7tuicdO+YkLbD03oq6kn9OTUNv9wV2RcxCBgAAOQJBMyT1qPT0nJsOpKuhpFK4t+bT1Ska/ekDDXcldLi8+m2QF9mM9zCvX54Ipo5cdBt+SuUMwXM23pmXrO7zsx3olurmuZpvUydCJs1XqbyET5OtD+UM6Y8sd5mxRXp3jkh62/MyFs/PC1r/+J9afyrt6Xlr92U9X/57pwfM192XAkzlbDOvZPSs31CD+PYcDvee8vXuur7/K2/pwTNli9b8n0CllUNdScV2tcL2059axej+/cJWLXvlO+HivB1eI/TavLl+aEh8X7NH5Ge0ri0vD8drQ9tPKX/OdfHy6sWBAwAAPIEAuZJJGAfJMWrYUT/yh3tZbXm48ReR1VP4LIuszec9Z1YVhn7XnUtV9ZzcStohbK/ijaLqkCqjbKagBXK8bARd0Ke3eZondQn2g+XXZTOPZPy9s0ZeeuPT8mqP/9Q6v+XT2TL/3p7zo+X55GG05VYwo5XoipYx76wCmbWgtVdij7DlDD41loVyqnPM7qeWaNotwoWdLU3IUjOCHl7KIypgiUqvbaEuc/DfCfsylqWgGW12trSFE5VjIa62Nf17Rnm+85kfKeDN05J7+CYNA3HlXIjYfVnkbDnGQQMAADyBALmiWlBbCxXUlWw1iPT0rVrUoqtD/QGtFkCMptf1V3BqvX3rPuZbcXNraLZr9upcHgrX54Wr0wJc0XPrDEy62nsOC2M0cn6145EFbHS0gvSuXdS1t+YkbrvTspbPz4mq37ykaz6yUdzfrw8j5jjz0yRbDmmB3O079cTEXu2T8hA5yO9FmzJqL/d1P4MXPHxVVfN3nLOHmH25xSNZbdvs2RUr+Wru6Tv3xbrjCmaCfmyqmuzEjD3xwFbvuou6TbhsHWy5sbN1aTMI3i9A2PScFoL15YzWr7MBu1zfcy8SkHAAAAgTyBgnkQCdioUsNN6AEfTyYq0H5iSbcUxCTZ+on/hr1X98l2eVeFy5cb+xT5LwqoJWY1KWuaggqzbuAJWKKcHIbgn8oVy3Gpmb9KbFXsgwmvHo5P20tIL0vHulLx9c0bqvjcpdT86Lm/9+Jgs/4mXe/2XyZYPw7WI4XFoBnNEExFNFaz5nhYOZwR8JGDmM7DbTd2qkfuZ2fvbObIUHUtGvpZdlNKKK1JaeVVvpFwoV5+iaUuYLWD29d01WNXaD63XWlpxRYY23ZFgw+34hwVroEzmBuPVJM35jvX3PpEtH8ZbVTQN688HAXu+QcAAACBPIGCeGAEz+1aZqkPrkWnp3DMpA52P9DQ4u/1wNhKUVdmqsn9R5nXdoRdua2I1AbOrFr5BHM6JaqptLEPcvOuNCuXkybw9ha9QTo9Ad+8nfMzS8svSvn9K1tybkbof0fJV92PjUvej43N+vDyP1J+tyJYPwyrYqbgKFk1E3DMpPaVxGWx/qDcvdtdV2Z9F+B4nhMZqq7P3AEvsweXKklXtDOaP6MrX8suRfJWWjPpbEDOk3j3mEtWyWUqYqcSVll+Wofo7enT+pjvJ2zjfBe8m47OpPM8blv7ux14Bqz9HC+LzDAIGAAB5AgHzxIySbjk2HbV6bX1Pb7DaOzimT3DtjYKrCZhvXVbWr/CeNsGs6lVqzVc16ZtlxS0xfMM3IMSWL1ec3HY296TYV/0y48jNIAZTmfENg9hwW5pOVuTtv3RPiv/HRen8G9fl7b90b86PleeZ+nOxhDUNV6TlfT2Mo/1APIxjsP2hBGtvpNoGU5+x24Jqv9dmrZ5JeF/e9j9zXCw8q9v9VlyJ5CsolNNthVlVsKyWW/c7ZlfzzB5ddkXP7Ce3/LIEaz6OxuanZM8+Tt3vle+7lFEFHqq/I83HK7LxyoxsvDIT/VjT8EFFNl2gCva8goABAECeQMA8MQKW2Pz2gN5stb/niT6pK5RnL2DOCV+qxaraL+1VTgBnXXHzyF9W1S1T+rKGOGTJlyV5wZunoz2qEhP6bAEzrW7hdRIjv988LUOb7kj9uYp0/o3rsv1nP5L2v/6xrP6pB3N+rDzP1J+Lt0FoPKXbEDMFzFPpciuUic/R/LtZJ+YKmD2cxW1ZfOOU3l5g5VWdFVfiPcleS09MnJWA1fhO2YM+EpMU7Q2ULXn0jcv3iqT1fnslzVSfzTG89oa0H5iS9ddnZP3HenP25uP689l8HgF7XkHAAAAgTyBgnphNb7e+NxXLVyhgg20PpLT0QroNK6Pq5WubmrV8VVvr4p48Zv13hoQlxrxniKK38uATsELZ3xb2erjn08Kz8Xh0t90tXDsUnSzbkhC+V0GhLEOb7si62zPS/b9fk61//WNZ9z/fe2XaD+1EAhZWWoyAdbw7Jd07wnH062/5Bcx8Tj4BM/Ji9moz+3OZmDHuzg8L0XqrlVe1+K2+LqUVV/RtCh4Bq1UByzrOnR87EgJviZa9FtF+zdFWB05FN9WeaU99zDim7ddeWnFFerZPyIarM7L+xozUn9WfS9NJXa2c6+PlVQkCBgAAeQIB86T1SNza5QrY0JZP4+EbVU7OUiO9P8tgjS8iYOZk0jcxLqvNy217dG/nvo5COSVfqZNVS75Mdcu93+i+TMWiUE6IbfHrR6X41UMy9PoJKTbfkxUz09Ly127Kqj//UOp+bFze+vbUnB8rzzv155LDONoOW5sy756U/t4nEmz8JLGxcWIYivV5JT7HUD5KSy/oFsJlF+PPLmwf9R7bhbL++7qbOmtv6OmH5vP0/OCQWt/1eeL5jkXHl7tWct5wcmy+fXzae535ho74qm+WxJaWXpCBrsey5UxF1l+fkU0XZqKtAhpGKrL5I6pgzyMIGAAA5AkEzJPopDYUMLsFMdhwO17/VavlMOskscZJpTuWvWZlwHdSnHUCaZI1hjtcs5UlkIkBHJ62tszqhGlhs1+TuX9bwMLnZp+klxafl+6dE7Lizz6RNX/hgbz1Pz6Vuh8Zl7rvTc75sTIXidaBhQJmb8rcOzAmQ/V30gLmEeboMzIxUwyXX9YStfCsHqyxZFR/jr7jYMEZKdVdiqcNrr0hpaUXkhUk91jLOvZ8PzpkSVrWd88jYNFgGbt6VignXl9p8flYwNzJkFk/RLxxSm/EvuVTaT06LRuuzciGazN6s/bjWpJpQ3w+QcAAACBPIGCe2Ou+jICZaXPBmo8lKJSzxcZ3QuiKVdbJpC1QhXL2tLcqspeSooyTR/tE1a1IJJ6De9LurifynaCa25kT+3BIQkrAzG2s6yXWoJm/rb0hrUemZdWffygb/8qnsuonH8nyn3gib/342JwfK3OR+rPxIA77x4JIwBruRgKW+Cyt4yohYNbUw9LSCzpLRrVcZQlY+BmXll6QYP0tGWq4qyVs9XUtM1ktfL51Xm5Vq5aA2d8tX/XZXG6v6fLJoxHOZRf167DaJqsNvkncz8KzEqy9IZ17JmXjlRlZf31GNp+fkaaTuk2UDZmfTxAwAADIEwiYJ1sP+gWsc++k/rXfHUbgOxmsVh3znVxmSYz5pzu+3RW1rLVbvvv03J/dzphoSzPy5FmHY1erjDBlVuF8lT1zud3qZj+vUAxKK67ItuKY1H13Unr/1hXp+ZtXZfvPfiT7fu7MnB8rc5FIwE5W9HEa7gXWvXNC+nueaBFaUOW9cUXEvM+Lz8fyZYZa2EMu7Mro/JFo1PtA5yMZ6HgkwYbbieqX97is9oNCVttttQE0rsz7hDPre/L6Cf06ll6IWy5NtSxrrzD3sRackdLKq9LX91QaTldk00XdhtgwoltF688yDfF5BAEDAIA8gYB5kilgeyaltOxiUsBsqfIJVbW1W57Lvb/Uu8LkyFFQKCfbpny/2Nu3CVNafD6uACy7GI+Kt9vSTPug777tdi+3ylbwjC13B32Y2yw6F7eBudIZnuT29T2Vt74zJTv+7qjs+7kzcvwXhuX4Lww/t2PiRYorYGYfsO53JmSg81F6CIf9froiXygnpgmW6i7pmM/CDFAxrXlm+MSSUQnW35Ji6wPp734sg20PJFh9PS1qjoRXbYvNarmdzWRE8/2xX5enZTZ6DLtF0UjY0gt6raJ9nRr7ggVvnpbSsosy2P5QWt6flvpzuu1wy5lYwNiU+csPAgYAAHkCAfPEtHR5K2BGwLKqWtVky3eymbHGJJIb5z6jk0pbpnx7crlx5MuMhjd7NwVrb0iw8RO9jmfdTSmtuhYPY1h0Tr83vvZD93lVa1F0K2HmZH7ZRf08ll1Mvp5COTqp7u99Im/98Sk5+POn5czfPybX/uF+OfkLJ+f8WJmL1J+rIWDhPnXRZ2Zu61sHVign14CtvKo/+7CSVVoyqj+bJaNRG2lQKEtpxRUZargrA52PdNVty6f687NbTTPaZDMlrJp81RpWY/+AUSin2wULnj3q7GNywZnohwhvNTlLxsIK7tCmO9Lx7pQ0fKCnHxoB2/IhmzI/jyBgAACQJxAwT8wasK3vTelq2MHpbAGrdvJYrQLmkzC3mpb1y7v55d4edGEqGPZQAXsfJ1fWCuV47HjdJb22beMnMlR/RwbbHshg+0MZbHsgxcZ7urVs2cXk/Zo1PhmDOjJPsu11OUYM192Uofo7MrTpjt5A19qw2bzO/h4tYGf+/jF59Ms75NEv75jz42SuYgSs+UQlGkHftTsUsK7HSQFzU63CuvCslq9V17RMLTijJTyUcXOfpSWjEmz8RAY6tHz19zzRx4+pfmUJUjUZy6ocVxkW47vPxA8Y9o8DhSoCZldiw9eZqNrZlV5rzaRpUQwKZSmtuibbimPSenRaGst6AEfD6VjC5vqYedmDgAEAQJ5AwDzxCtjBael4dypbwKqJWLX2Q9+Jp3Oy55Wx160x77MVMHffLvsEdf6Ivt2qa7GAtT+UYst9PXp/w23d2rbmYy1sZr1WNfnySacRMGvs+WDbA+l+Z0LvY9X5SFfk7ArO/BEZ6Hwkb31nSqb+8ZD8mV9vkfF/HMz5cTJX2Xx+JhawcP2XEbD+nif6szJ7Wbm393xeQaEcyXyp7lJU+SwtPq/bCtd8rD+TcChHsP6WDLY/lL6+p9LX91RvTl53KVn98rSaVh0S4xOqWt+nrDWHHtFKbCSdIXvBm6fj9stCOT04xyNgxa8flaHXT+jjuP2hdLw7JS3HpqVpWG/G3PCBzlwfMy97EDAAAMgTCJgnbYeTAtZ2KBSwfVPJIRxZv8ZXaz3MOqH0VL0SJ3nusAFnjVa1alRQKPslKaN6EBTK8aa0i84lWxVXX9cVESNhprJWKM/+fTESFlZY2vfHrVuN5Yp07NMbXpsNgINF56TYcl++9aQiP/0bG+V/+qeNcu0f7p/z42Susvl8OOrcFbCdE9I7OCbFlvvxe+e2odoybt9v+PfS4vNawFZc0UK+9EIkJaUlozLQ8Ui2Fcek+50J6dkePl7rAy1mZg8tO26rbKGc/h7Y67d8x2aVSprdjpu6rrXWK/qOVPmuDb12XB+TpuJn/chQ9ftrBsmsvSH9vU+k490paT0yLS3H4sz1MfOyBwEDAIA8gYB5YkZ72wLWdkhvdltaeTV5IudZT/KZ17lUWWfiyldQKKelZzZtXl8g0bQ3I2L2Rr2zELBEFcGcsJr7XH5ZOvZNSeMp3a7VWNbrmvq7H0dVvNKyizLY9kDevjkjf+033paf/o2N8p1f3Tarz/Jv/V9r5Du/uk1W/eQj2fJhJdq0uONdvW6qa/ekdO0Ks3tSOvdMSse7el2VWQc418ejm83nZ2TLh3oNWMe+pIBtK44l5dVa/1dafD6ujPrkzFxnxRUt20aww0EcpVXXpHdwTLp3TkjXrrDi1vtEhurvRFMso0mK9mAXW/p8o+ktAfMezz4Bs9d8ha8hq1I19I1j3r97r/fGqejHBrMXmvd5uRW4UNwGOh9J165J/b8bh6ejfdrm+ph52YOAAQBAnkDAPPEJmBnMEay7KUGhPDsByxKxzyBgiapXoZzetLjGmphZPYdZrNkJCuX4ZNyudliVlIRk2SfIpurmrF8rLRmVYM3Hsi0Yl63vTUnz8Yq0HtWtnv09T2LRW31dBtsfStPJinz313rkp39jo/y5f9pU83P8uX++Qn76NzbKgZ8fkVXjuiXMVDcjCds7GYtYKGCde3U63o2vM9fHpJ3No6GADccC1rlHS+S2YFwGuh5H+3h59/hafD5ZnbL+PaqAmTVfpjVx5VUpNt+T7p0T8WMVdbWttPJqcpS9PVTF2og7KJSrCtjnirWm0KzViirHXzuSWKflruXy/tDx+om4FdMZPlL1B4r5I1JacUWKrQ+kZ/uEtO9PDvCZ62PmZQ8CBgAAeQIB86T1SCxdtoBtfW9K/9o/f2T24lNtvZgrQxlrvaKTPKtSkVovZq/n8rUZzkYAa7V6FcrJDZbNXlMZgzei5xxeJ3otRr7W3pChhru6pW2nPmnt2Del14J1PdatYCuvSrD+lgx0PJKu3ZPS8zevyg//ap/82D/Zmvn5/X//9lvy+/9mpfz6v1okV/7BAan7E5Oy+aMZaRrWghdtXmxVwqLstbInlrO5PibteAXMWgfW1/9Ur9sK1wJGrYThhsPRWHlPm2BKwOaP6LbbLZ9KX//TSErNer1g7Y14k+ZCOZYws5eYed61hrPUqnplHbuvx6Pnh14/4ZUvI/2Z3zHfd8jehNq0N7rr2+zvRziOvth4T7YF41EF1WxnMdfHzMseBAwAAPIEAuZJ65G4dcgWsa3vTUmx+Z4eO21OBp1Kj1d6av3KPxshsn7ptzeLTQ3mmI2A1WqFzBIwW8LMSXvW5EPzfO1BHeF/mxPVvv6n0rNdD9/o2j2ZGKfe3x1O81t3U4qN96R3YEy6dk/K6kcV2fzTdzI3YW4sV+Tpr2yX3/q/l8iv/MslUve9Sdk8quWraVivm4ok7D2rCpYhXlF74q4XR8KyBMxUpnq2T+h1YOtv6fdw7Q0J1t7QbXXhRstRK6IrYEtGIwErLRnVVawNt2Wg67F075iIpHVbcUyGGu7qcfW2XBfKqbWJ3mOyVtU163uSJUzhc0gNyHD3D8uqPDvft+CNU/EQG3d9mfWdsP+9tGRUhurvSO/AmHS8G7ewImBffhAwAADIEwiYJ61HphMSlhCw1gdSWnw+KVbzakx3yxKb2QqYOUn0nIwmpiSaE+CsjXDdx/6iEmZXt9zXM88zEOTN01JaekGKLfel413dcth0UguReX879k3pYRIDYzK05VMpNt6T/t4n0rVrUtoPTMmWMxVZc39G6r6XFqJi8z0pNt+TlmPT0vM3r8quv3te6s9WtEgfnpbm41rAWo7pz9c83v/P3pvFxpEue3557517fI67oUbKkkYUJF1SOloOF5FFcSeLSxWrMrVa+76ymmRzaW7aKUoUxbXIKtqwPQP7enztMfw2D34bPxgGbNhj2BgY3uZhbNhPF+N1bGPgGVx7fIHwQ3zxZeSXXxapPqKo6o4AAq2uNSvzK+L71T/iHyEIUxCj+5wu5nXu9rqk1AD2JFyCyEspuy6FFb2uS+vYG3bqlX2kAJUQHp4IZoGp+XCZlgXoyaxC51W8Bl2X19Hu/sSLQI21KbWm0UccgMWpyDHrPbTmv3kU/u7Z3EO3AjD+/uYPCOpzRO4zf3TYo4w4amahr28lDGA3BMB2OgXAJCQkJCTKKQTALNl6BzfozQ/RwYxs6dtvbkBf3wpuPN1cbLleBJxKlSvGlSGy5+iSKiqrotfhG9JvmUHHVspDKfCK6T8rCWBuLmpMwje06ja/Ygx606uQGCxC3eQm1E5jnhlDhYo298mLqIr19q9C9znsOWq9W4CzTwJb78RgYO1d82wTevtXoa9vBTqvrMPRP1uD3/2783B8rajNU9pvqJIwo6SU94Jp4Lqg8rxKBWBfUykwmgneAAAgAElEQVRiYhBBkpuJdF5BQGp6VMRzO6OSzvOPm9CYK0L3uTzOXDs8EShVyuzEO/ECvNq34NW+hWziPaSSS5A8n9fGJN3n8vgjxNGpsDugUaIXWiPcBdEcU8DXmkVZ4qWDNviyqsvmGt7qBw9exmgDLVrf7L7IbLFvH+NnrH4DfakVDV8d1zF3e7383FMATEJCQkKinEIAzJLkYHb2CZZ5EYS139iAHm8NsnVz4O0ftm7WrKCznTKrLaAoAmEmgO15GljH8xlaNnVquwBm9qDRZtTNhdQv+q/1M7Pj906+hPabG3Dmx80QIJwZ34Smx0XourQOfSmcK9WTQfgi04eW+wWcqzSkUs1WaswVoW5iE46tF+FP/voGHP1XEcCOrxXhzI+bIYC2map0Xl2H5AW0VNewdcGAMKWGfU0ARoYi1PvVeQVLOJseFaF+tAg1zzZ1cgirm0AI68msImypEkSaAZetm4NM8wfob12AVPdyCL46rm0EypebC19rvuZtEGZTS831ZlFNSdXaEr5sirFRlmstaaRjtVnkm+veAEPzNb39w5Ctm4OezKoA2BdOATAJCQkJiXIKATBLtt3agNa7BWjMoS06QVj7TTQfoLlHkV/Ebf1Q2zXm2AYYZX59HzJ/fAcyf3wnvAkl+FJOd7qs7FPhy1bWyDfTZrLZY7HQycEu8R6aHxSgboKpMwrAWu4XoC+1gj12tW+hv/2jhp/Oq+vQ/KAAiUGEi/pRnBmW+D4Ydvvb5SIc/dfzcPRP8/DbFYSyxPdFaHoUlBySLTgZcFCpYyq5BOmuJbRY58DFShGptG+31ybl2Seo7vHyw9a7BWgYRvWr5jmDLwZgpIS13Cugg6GypvePPUP4almAVHIJetOruueLVMLkxTzQkGerumtRQEPQztZMxBTDUraq1xRfk7YyWRuAqYxTsPhzuFlMZA3bVLCYH1m8AyOQbXiHLogCYF80BcAkJCQkJMopBMAs2XYLB6kmBos6zz7FDW/X5XWcUVU1E2wiWR+KuYGMBTNbbtWPxZQwvWFVjoJ+5TT27tDsorhf/LfxHrEW+Fz12qrfzaJOpLuWoPlhAGAECGfGNoP+uuPP0XnuxAvo9tew9+vGBpx9WoT6EQSruklUcqgXKjFYhDNjm3B6dhNOvw1KGpseq56vhwVouR9AWMc1VDLTHYuQTbyHbP0cZOvnoL91AfpSK9oUJC53e33ydaot869vwNkneH5qnlkAjEPYFA5y7vHWcM0o+CLVi1wp225tBEPIlfGGd3A0Hog4lJnKqaGgRlQwA8BiVTL2o4P1xwxbH5drmePFwYkflwlzRvlt7Jr/9rEeGJ68KAD2pVMATEJCQkKinEIAzJJttzZQcRkKACzxPW7kO6+uQ2//anQeWIzSZSoAHNqsv+JvBUikuB0cDVSLxnnINM5Dtl719bjGRrKUsYHlGEz7bq0QmGVk21XX1DGkOxeh7dYGgtRkAAb1o0U0Kqh9i+qK6qfpTaPxQ8s9vBZnxhEeTDWn4QdUKqk8kYw2mh+i8QYHsLbbBUh1q+HBJ14Ejn9VM+i42LKAjouX1iMzwkLJhjfv9nrlWTu9GS0/tADYmbFN6LiOYxWydXOQ7liEvtQK9Hhr0HUZobf5IZ7Dlnu47tOdi5D99rEuhY0AmFm6aoMwNxcdyGz2G9pKCc2yw7jvm1qfkV7FEgpYqEyRvp+fCmB7noJ/eAL62z/i+VPmGwJgXyYFwCQkJCQkyikEwGLy7FNVxjYUmD4khrCkreP6BqQ7F8E/Mlna2MKiHGmVqZRaZA6I5f0salZTtm4O+ts/Ygld7zKW7p14Ee3FituwxilwprphKAQhZc3cePP3stzuHxrHEi1/DZofYLlc/UhwTrP1c+C5Of0878QL6D6Xx76mEezpqp0KA8WZHzehcaCIzpX3A3dDMt3gCk5f3wp41W8gu+dpuKdOpbYSr5uDHm8t5CDISxLNskTb7bu9fksCmDpvTY+KaPt/IQ8d17E/rvkB9j42DmDS7LTe9CoOGrZZvNO6MY1iLD8cxP7gwMtc40pabevW/LHj4GjYXt80i3Fzpb8DJpzF9HuZx+DtHQTv1CvoyazqGWAEYOKCuPMpACYhISEhUU4hABaTie+LUP0iUFe4wtL8sAA93hrOV3Jz8Zuy7wbC7m/bUYoYBFmNB/Y8xc3lyZeQrUf1K5t4j/B1cDS2PMoKYAZAWTfXcX05pjphcU2MlIPtG0JoTbyHHm8N2m9gr137zQ20SW//GEDtN4/APzQOqeQStNwvQMMPDMCYoURiqKiVLerxop4l6lvq9tdwaLAyj8j86p7upQvlr+8jhB1/Dn2pFSztu7YRgS9yRDTh62vrF4sA2ExYAeMGM80PC3D2afBDA6m/jTk8v6nuZSy7tQC6Lo+l80rq2FZDjzng7x8ODGQMxSp2/VlSDwqnni5Tid5OKXAM4JW639s3BF7tW0iej5YfyhywnU8BMAkJCQmJcgoBsJhsGC6G+onOPgl6jRJDSrFJvNclcxHwcnOBBbdrQJoNumy9XiZ8cVVq7yCWIR4ax54pNRS55K/0ppJlwhepFzF9PCXhy7apNuaR0ebYPzKJ5X5N85DuWIRUcgkhqWsJVbADI/icAyOQTbyHjmsb+tzXTSJA1E1uQv0IwnD7jcDhkNQuUnbSXUuQaZoH/9gz8L4bCBmZ8Oz/o9sawvyKMUh3LgYAFgdapm09u50GS+/mGo5TweomNrWJydmngZFJww/K5GSkCA3DmIlBpYD141w2K7woYA6dW76WDMA317FfMaZnk3kHR0MuntY+SuM7EvnBgD3X9h3YlgIWB2Cmqkfr+8AIZJrm9bw6/iOAANjOpwCYhISEhEQ5hQBYidQA9gTL5BoHilp9aXpcxDLEirFgc2b+2q4AzNr3FVOymN3zNB5sbOYYpjoQ038VsZHn5ZDmZtbsjaHHG6505gbbZikeATCCsEPj4B+dAr9yGrzTr6G//SP0t3/ETf6BEV1u6dXMQre/Bk2PiroP7Mw49o01DhSh7XYB518pCOu4rmaJXVDDnOvnEL7cXCx8EYARhHluDrIN7yB5IR8ecGwpRbQCGLOFb7lf2NU1bIOv+lEFV0MKtH5QJZ7s3Db8oHIYIa3tNpYhejWz2Dt3dAphySiv1eeYlyPa1sa+IexXPPECleSTL3E9HBpHBYuvOXOd0/uYa9aEfxswbVUKaVOLbX1fxvfdPzQO6Y5FPaxaAOzLpgCYhISEhEQ5hQBYiTw9iwBGTnpNj4twenYTTr1HBab7XB6NMAwAM9Wm2F6WOABjYFQSwGy/0nOlzNiQxikJcQAWATaudNiMGEoYJkRUQVLvKsZw033yJXi1b4Oyzt88wMeffAl9fSvQdgtd/ggKGnOozFCJYOeVQK1KXshrl0O/aga8vYOQ+fX9EGSVAjDqPyMzjrhyQ1vaAKx+tPhF1uunJPXf1Y+isnhmHPvCzvyIa57OM53rs09w7ljX5XXoPpeHvtSKdpH0Tr9GIxOlxIZ+RDDXwN5BnDeWeA/pLrT/zzTOg1czi46MRyZDLp6mukXfD6v6ZX4ftupD4989Y+yCrYTW+v8EYFUz0Ne3gr10t4K5aR3XBL6+RAqASUhISEiUUwiAlcjTs2pI8CPc7Dc/KMBvl4pwPF+Ek/Ob0HqngNCwdzAWwKywVcJJLQJSpVzgbOWLJqh9Y7fIN13oQpvZuJJF3uuzHSc8E+RIAaOB0dTzowYBeydehEoFs988Av/olHaWa7kXzGZrfhj0jnWfU4OUlRLVfS4PfX0rgZr2zSMErD+8GQYw+hwmkP3qnna068mo2WDn8XW7/bVgVpgCLdvMMFLlCMDOjG3u+nrmWT8aKF4EX3UTCsDGwypZ4ns2D085SlLvXudV/Nx9fSuQ7lxEMxgGU/7hCVS2jj3DvkU1qLjjGj63J7OKpacN78CvmtEARhBn64HkABb5XmwXwMwfP8z1apbzWkohdZIBh7cG7TcFwHYjBcAkJCQkJMopBMBKZM0zVLoaBxSAPSxAVbEAR/9sDY7+jTxUv9rEWUqV09ZSqVC/iZF646YAJOTUZlp0lzK5sJlqmCqYYaYR6X+JU6vUsYSeZ5otmCWVpcDLPMe8LHL/MKpVJ19iql4gv3IaMk3zkLyYh9a76NBH8JU8n4dU9zL0ty5gL1n3MvT1raDNfN0cOhp+8wgVrj+8GclSvWDZbx8HNv/NHyDTNA+Zpnnob/8IqeQS9Hhrel4YuSV2Xgn+3XENy9Ba7hWwvG9s86uBMK10/RiAFyUBGPU6Eng1PcYy3JZ7hSDVjxLND5QByp2Cdp0kJ0puREFw0n4DwTnVvQxe7dtgdt3eQfyvKm20KcvW/i1b+WCcQmz74cNQwELW9fSdoO8p/66q9etXjEGmZQG6Lq/rXkQNYGJB/0VSAExCQkJCopxCAKxE1jzDvpnGHG4+mx4XoWqzAH/yb6/An/zNVTj5YRN/4T79uuQv5BH4IaMApQTpMjyyz6bNZxyAmf1mcf1ftn4w26///Fd+8zzQ8atNaagEkffelOg9s5VlRs6Nckj0Tr1CI46aWVRMEu/RkfDKunbro1K4VPcyukCqWWj97R+1CuMfe4alh7+6F6hfPP/gRgTEqAyx/49uazMO//hznPlGWfsW3SebP0C6cxH6+lag+1xewxepHl8rgGnwGg+XHYYAbGxTjwfQKqO/Bj3eGnSfy+sZae030cWSFDEz224XQuDVdgv/3de3AtnEexy6XTEWgi3PzQUuhvx7xNZMSSfDrQCMq8fmDwfqO2b9UYQrtnwNuznwj05BKrkEnVcZgF0TAPuSKQAmISEhIVFOIQC2RdbObKJbnJqNVFUswNF/axWO/ptrcHwVbbyzifd2+HJz8WVLbi7ohTo8gWYUJ15gGdbhiaCs0dbzFVciGFeOuBWYsfJHz82FFCt9u9qQRkw4tvPaHMjY8UaAdP8wqiHVbyBbNwfZxHtIdy5Cbz+WAXZcw7leXZfXIdWrhikrxYwen2mcx56kQ+PguTm7+vUHN8KpShM5qGV+dS9w6KuawR6no1NYVndkUl8vr/YtpDsXNYTRxrvzKvaAtd5VFvpfC4CNBwpXpPdrPOj/ahwoQo+3BpnmD3g+jz9HGFWAnGn+AKnuZeg+l9ewSbPX2m4HSpi+XWXyQh7XecVYMKuL9yN+8yh8zHyN07rkNvVxEGZ8T6xQFvODRATAlONoBMDoO3zqFfT2r+r+r7ZbG1oJ3e3r/UtJATAJCQkJiXIKAbAtsuZZUIqV+L4Ix9eKcPRfW4ejf5qHY+to053uXMTHm06D/DYbgLk5PVjZr5zGfrLat7jhPTqFFvc2p0MOMyYsmaVZ5rBc09TABkjGRpcUKs/NRQ1CbIAXp7IZiljos9H7svORbXgH6Q5UmfpSK9CbXoWezGpQYlg1g1BUNYPmHTWzeO6OPdOGEBrAmOIVATAOYkwV89wcQmHFGAIDlcmxc+IfGgfv9GtIdygIu7oeyrZbG5AYKn4VfWAcvOpHizr1bSNFDV+tdwp4Pg+O2kFZgalX+xbLMruXIZVcglTvctA3dzGvQZTcKVPJpcBq3piRp6HeVJPpM9gAzNbfZSkHNh8TeT4HMFvJLB/uzG73K8Ygm3iPPxCwUktSRHf779cvJQXAJCQkJCTKKQTAtsjaGdyY0oDakx82ofJfLMCf/EsFOLaOw4F7+1ejGzajTySuNFFvag+MgFf9Bkvc6ubw3ydfojpGm382H0kPnGVli7aNptnnws0L6LUi6hd/XZ5crdhC6Yo8xtKLs5ViSO6I2fo5yDa80+nVzCJ4HZ4ImzyceKHTr5wG7+AoliCWgq4YEMv86h4ejwUUTFMIv2IMvFOvIN2xGPSEqQ14+w2cYUYztr4EhEUULqZ6cfAiF0Q9+0vNBmt+WECliplhhHqkaP0dGMEfCpQK6R+dwjz+HFXMhnfQ27+qXSqTF3EuWwjA2JrSxi6m6QV9NltvpbnWTXV4u6WKHMAs/Ztx/Zp+1Qyku5ag6/J6SOkTAPuyKQAmISEhIVFOIQC2jayb2NSW3KfmNuH4ahGObRTht8tFqJ3ZhOTFfDC7iGeM2hO3cfQOjuKG9sQLXYbn1b4NYOzYMw0eunRROc1F1Bnbr/9mrwspGYfGdRkkudXp91Mqk3dwVH/GyIaXb2CpXNHNRSHMLA1zc3Y1gykRWmk58QLL4JRTHrew1xBWNYObfzp+ZY4SUsG2CWDZ3zwI+t4MZ0pz4DCVrfnHn0OPt6ZdEAnAGnPFwPZ9ZGct6SMlhgzCIvDFkuCr6XER2m5tYIkncyLU4M4BjEpoq2bCFvS8x7H2LQ7aVk6VvelVDcca8t0c9hZyAONKlu37VAqizOeYJYe25N+NOKWWK3D0+jWz0OOthcowSe0TB8QvlwJgEhISEhLlFAJg28jaqWAuUt3EJlS/2ITfvd6Emue4wW2/sYEQZDikxW76YtQj77sBhCICCjWYlnqOqAfHq34TmEJwUDv1SitmumyOD8sl1eLQOP5y37mIwKAUCrJUT/Uu41BkmvFUNRNslE2zj7jNr6mUffs4BKCem9PKmtVAhAwZyLL+4GjwWdht+jPuHw4A9tQrbZbhV80ERg+0ySfDDRPKSPmiIcFqIDS33bfa1nP7+qNT6Np4IY/DoW+jcYhWwXYQwKzwZZYcWsCrcaCoRy2030D48o89i15buibcPGXvYFAua5rGEMwcHAWv+o3u50sll7CElEBM9RZGRhsQqMeV2dqcDRl8hdZVnINizG1WFcyi2Pb1rei+N3J4pO/Sbv/d+iWlAJiEhISERDmFANg28syPm+F+GaYonH1ahI7rG+jgR6WAbi6qdm3lQrjnaQBHStnyDo5GN4VMdfBOvNCwwZUyrRYdexbMYzoyiQBXMwuZxnlIdS+HXNvab6BxQNel9WA4bvWbAGDcmJlmW5UaGn03obIy5SxnhTquYhB0cZDks8SoPJJcJcnIo+EdfgauHCqoCtnpq8z+5gG+1qlXmAdGghJG7pDI54gZEJbd8xT8ymnoS+HGvPUO2rQnvt89ALMpX/SDQuJ7hC+ykk9eyKO5CZ0nfv3U+4T6EFWpqF8xFi1XZGWaHMJ0H5+a/UWDl+OGK+vPaOvnspW1mgrsdkHLcnsINs0y2f3DkDyfh9Y7aMuvZ6NJ+eEXTwEwCQkJCYlyCgGwbSbfzDYMB/ORWu6h5bRfOR2AgKmC2RQjs8SKFJxD41jOReYHRg9XSC0jRcsYdhvKU6/QJr9uDjJN89o6nUwD6Jf7zqvr0OOtoUnCqVeouFFpI/XpmOVeNqCMUxZ4X46bC5zl6HPaNsa2a0GbX4Iw6k8zLMPJICJbpyztq99o5dA//jzoIVPn2z80jqpPwzvINH9ACNk/jNDFDTo4hNkUMdU7lmlZCNm0Nw58QQCLMdswwYsGKzc/QIDouL4B6a4lPHduLlhz3z4OwYcJYN6BEfzBYN+Qte+QlDC/Ygy82rdoZ++vBXb0SmHNfvMoOhCcvU9oTVmAX8OXrR/SokZbzW0sAGY119k7CP7hCei8ug7NDwrQ9Bghtu12QY8j2O2/Wb+kFACTkJCQkCinEADbZmqL7mEs2aJ5VPSLt3/sWQArtjJEixtgyP2PqzhxPVQWZcHsUfEPjYdh7PRryCbeQ6aFDStOrUC3j6WHyYt56O1fhf7WBVSLCCR5v4tp+23rYdvCcCMEVax/KOSyF7f55dfC4poYmdlEdvY1s2jgUaeyHueFpTsWId2xiHPDOhYh3bkYzPTy16Ano87HgZEAwAzL+lIlidlvHoF3+jV0XV7X6sjZp4ERx46u0TjDjVFVbpgraligeV0t99A2vvtcHiF1/zCWBDIQonNu9l9pN0gCdrP0lK1Z77sB8A9P6Nlp3efyAYTRMHPb+t7GWtNrgr47Zq+YpRQ49B2NKWPUaX4f9g+Dd/IltN/cwBEV6geZ1rsFga9dSAEwCQkJCYlyCgGwbSZtbMklrvUOwhc13HsnXkQBzLWU7dkAzM2Ff7GPcWcLbWgt/Tlm3xTZs2daFqC//aMeVJxKLkEquQSZlgWgWVq6hFIdSwhymBGFvs0Gl4YCFlvGxTexXF2zmJVEYCsOwHiqEk1S/TSE1avZYgRdXUuQ6l6G3vQqdJ/LQ/ICDhnuurQOvelVdGD8zYOoSccWClj2Nw/Ar5yG3vQqtN3a0ABGA5l3eo1GDDcUfJ19goDQeWUdkhfw89JstY7rG5DqXsZ1oJTX0Kw3UqFilEoqc9VGHGpdmGWF3ncDkG14h3b1Hg53TvUuQzbxHr8vTHULmZ+Y69+mgLE1Yq6nCIDxXkUDwKzqK4cv1SOYaZyH1rtBeWliCMG2/YYA2JdOATAJCQkJiXIKAbBtJpWPnX1ShLbbuGGlgbtdl9ZROTDnG7mW2VylSqriZmrZyv5scMZfQ/WU0aDgbP1cUH53ZDJwTTTVOtP1TX2ekELFTRFM4wyzT8csJ7SBp6mWcUMPeixZ47PHe24uNDuMTDn8wxOoAKpyNz037PhzVGnUa4WUQmXakU28h/7WBa2QeTWz8SqYxYhDl9upDXryYh6aHwYliF8SwBp+wPEJTY8RvNJdS/hZCWT3DoJ34gXCePMHLFfl19oGOzEqp1ZfD41bB3ZrUP3VPVQoq2YgWz+HymNqBXoyqzhPTx1f7PqOK3U1v1O22831GPf4UudZOXNm6+egx1uDxKDqC1WDrPUMta/gb9YvKQXAJCQkJCTKKQTAtplnn6oZSQ8Ct7OO6wzAaGitrQTRKG+KbAptsGX0qUTuiytNpJIxVRZGM8X8I5PhYcL888X1wLi5sALGIFAfV4yyF1EazDJB/t78c/FZZVw1I8hyoyYQup+MuSUSiKW7liDTNK/PAZU86n4hAjt6DgHc8edBD5mbi0KYacjBjTy+GwD/yCRk6+cgeT4PTY+xbDUxuHMliBHL+ZEAvtpuF6Dr0jpCz56ngXr36/v4fBr+XTltBzCz9NUsMaX1QGWl5GxJ15KrhL+6h48lI5maWcg0f9B9iSEIi/shwgJfkZJDi6Kq1wr1DVrWYuQ203Z+7yD4Ryahv/0jdF5ZR2OeHzehbgIhrGEY/0bs9t+rX1oKgElISEhIlFMIgG0zmx7hZrblngIwVX7YcQ1LELMN7/QsJM/NRRv8Y0rsYtUts0zKvI9tiiNzmlQPFNnWE7hY+6rM44gDMK7S2Xp0bBthrpgR7MQphHyzruDA7O3xD43jc+JKOtXjQsOjT7wISizJxt7Wf8fNPFg/nXfqFapk3w2EbetjnBFpwLV/eAKydXPQfQ4B7OxT7BNq+GFnAMx06NQlh3fQFCLVvYx9XWTBr/rYvO8GAtdMpV7p9WYDMBtocygnoHVzgdOkkdk9TwPTGaVWZhveQbe/Br1p7L/zq2YCwC8FXFsAWEhBZbCtgZ07adp+IDABTLlk9qZXoeVeAc+3ArC6SYTgpsc7O+tNMpoCYBISEhIS5RQCYJ+QLffRtEDP/LkZqGCZpnk0fuB9StsBsFL9XnEKmNFbE+qxUY50eo7YkUk8fl66F+f+ZgIYgZObCwFYyKUuTnVQ7+m5uQCK+MZXQVhEKeGzoGwARs8xz5UJYQTCrDwxcm34sXH4Yvf7FWN6Flp2z9MAwgwAIwjLfvtYqyRaAVPw3vQYIWwn1mYEwJQS03F9A7ourUOm+QNa6pvHenAU4YvP5DKVWbP3kJXpRdarcubURh4cvtQ6DYGaSv/olO5P7G9dAK9mFq83rX1TybKkFbzoGtOsOHMd0r/p//kYCX6O2XrIJt5D16V1SHwfnPO6yU2onUIQ2+2/U7/EFACTkJCQkCinEAD7hGy7XQhSAVj7DVTB+ts/olJi2+THwE8EgEoYDMSV6fGZSZ6LygsNY9aKkzqGyHvHlHWF4IsrIgzAtDmDpSRMl6Ox2Vxa7eDHZvYKcfWLAMzNaZWKBiqbxxOaF8XMEiK9Ym4uqu7FKSD8+ik3SV7CZ8IXKUrZPU91+WemZQE6r6xD80O0om+5X4CmR18AwFQpHFnLawD79f3AKOTbx1huSfPiKsYCAwtTYbSUAtL7mvd7bi44p27O+kNB5LyrDJV9nn6N36eDo/HlhFv0Eur7aB2azzHnybGRC7bX9/YOgl85DemuJWi9UwiZnNRNbkLtNILYbv+d+iWmAJiEhISERDmFANgnZPuNDRxczJIgLJVUBge23hI3F93McTizlfcxZScEYbaeL1XSRQNxdR8P78+JK3u0uRe6uXCpIJWCGSWPITdGE8JYf5VfMYbHRgOhab6Ym4u+LgEYqVpuLigTZCWE5rnQ0MgNQpRSZiokoV4gE8CM1/DcnC5FJCMPz81FIIxUO88NVLO+vhVov7ERqKa30fJ9J9amFcDuF7RLZ6p7GaH0m0cIiFUzaBxTMxvAFztnoR8AzN5DDmCGeYxWt9T3wPZjQWSGG60zZXDhV81oVS6kgtkUzxiV2Vz/+nOZP2pYym1jVbZ9Q+BVv4Fufw0aB4pQN4Glng0/BAC223+jfqkpACYhISEhUU4hAPYJ2XEdYav9Zhi+2m9soG05bWaNpv3IvCoGYNZyL5vjm6GEUWmdLjdUJhtWN0WuDnGYspU7cuWLm4nYwI+bMpi9N24ugELqjTOHL5dyfjTVDjdnPy517vT9/DwrFSyiemwnTdOQfUPgH50CmiWmwYADwd5B3c+U6l2G5EW0eac1QutmJ9ZmyITjR/z32SdFnFN3Fee9pTsW0ZCETDeqZlBhYudbg4pZYsqvv1mCaBsQHgPKHIj5jxBx5YSR7wgvgTXVYrOXstR3qtT3y1bKuG8I/GPPINW9DC33C9jzNbEJjTk0O5HSw91NATAJCQkJiXIKAbBPSHMjzQGsx1tDI47DE+E+EnNWFS+N44rUNi23PTcXDL6tmgkG4JJFuwlHpv8eOA8AACAASURBVJLkYtlYqIzQZqLAFSHX6PWJccUz+260oyCZgLi5UH+QVfEzSxn5Rt0chMtUG17qqPt5uBq5XfCKUcH0Zzr2DDKN85Ctnwv6pqiE7tA4ZBveQbpzEXr7VyF5MQ+dV9a/CICZCtiZMYQDckDs9tcQwBrn0ZRErVOrSmorQTRdNtX7Wnvx6HzzMlcb7NiuMYPAiMpqM50ppRqbQBb3PbMofKHvG5VMKvWrYbgINc/wPJ99ogBMSg93NQXAJCQkJCTKKQTAPiHbbwabaLMEMXk+D5nmD2h6wVUui/oVUYxs5YBm75dSWLyDo3p+FTdO0K9rU6k4HLHHabMLA8B0KSMzzIhsYG3wxT+r6tnyD40HkEJQZAPFmI15aJOujj9UPqhALKIGHp7A9zZK3CL/5mVw/D6bI56bw/c8+TIwi6h9i/OzTr4Er/oNwld6Fbr9Nei6tI4KGF83t3emBJEbcNBMqsQguiASfJGjo7bzp+tpwHOsAYdFxbLBjH6dmPJFnhHAdtkPBNyQxQJfIQCzKbKmOmtbv9v5wWPvIM51a5qH9hsbUDuzCdUvAqfJxGARamcEwHYzBcAkJCQkJMopBMA+MU0AIwhLXsyjffbRKbvVuZuL9mDZfpm3lPPp8raKMT042D8yGe71spSKhcwsDHUj0sfFAE9bt9Pg4gMjdgAjNYSXCFrMN0Kp+pBiFbSYUrQInHFzj0PjCFwcwAgibb1dDBJjAcy89vy4Do5CqnsZejKr0JdagXTXEqQ7F7Xy1e2vofp1dR06rrO1cruwY0N6QwA2jgpYYhAVsFT3MoTm1JkqlwlgZp+gRVUNlSvaSllta92iOIW+IzZnTLVGbWYe3IDGWopo+zHDNJHZLoAdfw6p7mVoelSE6hebUPN8ExLfF6HpUREahsV2frdTAExCQkJCopxCAOwTM04F67q8DqnkEgKSCWCUpTalMQCmVanK6WCu1/Hn4YG5MRDGBxrzDWgIzkjNcHMavtKdi5DuWIRswzucEVUxFn+8NvWLQIY7zKnNP99c888bOVduLlD2bADm5oJZUqrPTAOXOtdW8w2bKkmPN9/fLItjfUmZ5g/Q4yFoJS/kIXkes+vyOnReQeWr4zqujdY7hR2FL8+NB7DWOwVcl8efh88nX4Nm+ahRGmsrV9XnI249xAGaDcCM6xHqQ4spOwzBl/meXP2iUl/b98Isg+VKGe9l3DcE2TocKXBmbBN+9xoNN84+RQCrHxEA2+0UAJOQkJCQKKcQAPvEjAOwjmsb0JNZRWc55fBn3dSWKju0qF/egRE0Szj9OighOzxhBwv+HnxzyX/9Z/OY9AaYZmydegWp5BJ0XMOSynTnIni1b7G3Ke7YzU00n6ll3GZTNkIbZX6uqczQgLBIzxBBGJVMkvteidJO/j6xCputL4ltzr2TL6GvbwW6Lgew1XGNpTJsabuFLoiUO7UuQ/A1vgn1o1ga13q3AH19K+CdfBlrNBGCDf55bQBmrtFPBTCzBNHN2XskjeeZJYehYzJLbOP62mwOnuY6NtYE/QDS3/4R2m5tQPXLTTg9qwYuq/lu9aMCYLudAmASEhISEuUUAmCfmNx4g4MYuc2lepcjakNoQx9XjhhXZnfiBapQh8bBc3N6o2gt2VOva/47pCh8oxwD9w+jtXrDO8i0LECqexm6Lq9D84MCNObUxj21gm55ZFNuHjvftDOreL9iLBhqazNiKOGmGCkV5POZzOvBPyvZ3XOrezL7MHt+zP46M021zPK5aSBvt7+GZYbKZl7PhrsegNhOKl+UIQBTJhyJoSI0PyxA8kIeson38cos5XbGDpjAb57fUgBm6/Pj6pfte2ErKfzmUQjGQvBnUTZtippeB5Zrbqpk3v5h6Lq0DrVTm3Dq/Sb87g0anLTcL8DZpwJfX0MKgElISEhIlFMIgH1itt2yAxjd3n0uD9n6ucBq3bbZpNezQRjfDB4YQcWLLM9tVt7stbbMvYNYqnf8OXg1s5BpmodM0zz0ty5AKrkEPZlVaL+xAc0P0LhBuzoSAJUCMF4OyJwP48wXIv1FpppGsEDzv5ghSKhHiwGYd2AE3//oFDpEVs0EPU9maVqpXiGuqJimHOpc+hVjkK2bg57MagjA+FrovILliF9iXdoArGEYFZqOaxuoZpIyS6nWIwdX7+BocN2MEsBIP6FNZYwDNNv9BO2Go6X1O2EqaDFjFPyKsfBQaaMs11puaKQeCE6z3fYPQ8u9Apx6twknFzah5hm6H7bcxx8rdvtvkqQAmISEhIREeYUA2CcmqRy8xIxn59V1SHct4ebfzUX7awyDh7hNoOfmgr4mDl+/YYOHY3qUIuoYORseewZezSxk6+cg2/AOson3QDOhvOo3kGmah77UCvRkVhG++PwuC3xpACN3RoKvwxN2swfTEMFWnrbnaXSGF0EYt8dXx+K5uaDMUf3brxjTPXP+sWdhsDBL72xlnyZ88Wun/t+vGAOvZhb6UivQcS0w2aD80uvSWoI4hC59bbdwTl1oRh1TGTW0Hp3Ca86HZHPVkgFUyRLPUgD27ePodePKm61M0ujpii193D+M4H10KvoDQMxxRr5/VO5IEPbr++AdHIXEYBF+u1yE364UoXYKAaz54Ze/zpL2FACTkJCQ+OVE3nGc/8BxnD93HOcvHMf5Px3H+S8dx5l3HOefi3lOh+M4f1s99i8cx/lvHMeZchznj0q8z0XHcf5Dx3H+keM4/9hxnP/ccZzHv/fRYwiAfWK23gkAjEwWuMtd+80NVI/q5zQ8hV7DUKVCG0C+Odw/jCDj5sK/3pcyHrCZKigLbXJP9GrfYp58GS4t3DeEoHL6dXCfrVyNvx8rleTwped+2UrU4sw8zGM3Szj5Zt3NhWGJzwOj46kYC/XOeSdehDbmZs9cRK1U5y5upIBfMQbe6de6dPNrA7CGH4ro0vcYnRC7/bXwjDr++Ug55CMD9g5Gy0Z5+WZMeaGtF8sKYKZhi3lNuBGGUXIbeW/6vnDoZiW7W5WZRoDcKLv0D41D7fQmHF8NAKxxAOF2t/8eSWIKgElISEj8cuKfOo7znzmO82eO46w5jvMvO47zdx3HAcdx/oHjOEeMx//zjuP8pYMQ9W84jrPhOM7fV4//WzHvMa7u/4eO4/w1x3H+BQeBDxzHKXyGzyAA9okZArBrUQBru12AjmsbaP194kX4+ZaywMhmltQvNUMrtn/FVAhMgHNzQVngkUldkqchhDbYfEPq5sJuhXGbalMBOzASwBepZuZnjBu6XKoHjp8zVr6pzwlTzPjn5xDmnXwZJO+nM5U0M93c1gB28iWkOxYheTGP60A5HX6Jni8zbQYcjQPo0td6F4cx+1UzW/eBsbSW7pmq1HZ/FGDXXaua/Brw9WVbl+b9/PX2DuJMPBqdUDkdVsDMckamMpvfT/59I5MPv3IaTs9uwm9XinDiIzogJoYQcHf775EkpgCYhISExC8nfh1z+7KDgPTX2W17HMf53xzH+X8dx2kyXuM/VY+/Y7xOpeM4/4/jOP+H+jeF6zjO/6Ce0/6TjjwIAbCfkG23C9pogXrB+KDdttsF6Li+gSYWVBpHafu1f8/TKDiYIFQCVqxmAubQ4TgLcnMTHaNS2RQj77sBhLvjz/XG1zs4qjexuudMgZ/e+JpwFtOTE3FSNPt62ObcVurouayMkw+HpllhtjlhdG3oWtlmuu0bQrA99gwyjfO6d67t9udzO2y5V9BDfutHitEerx8Du/kzYwhd9SNFVL6GitoiveU+rsfOK+uQTbwPBoXz9zNL/2y9emb5oMtA2JY24OZrib13SSWXyk9t15hez80FZad0reM+l60fjV9X03Vz3xBkGufhxMdN+O1yEU6924TameDc7/bfIklMATAJCQkJiXoH4ejfZ7cNqNv+puXxKXXff2Tc/lHdvmB5TqnX+5QQAPsJ2XoHzRbMMsQQhN3C4czWsq+4ni21sed26lYDCbPHq0QpXQhSjPezqmtsMHMI0PhmlXL/MHinX0O2bg7dEo89QwBTZVz+oXHwqt9Af+sCZJrm7WoHL28zAFCfL16u5hrlh+bmnZ8jglnTQZFUQXJLJHMPEzA5gJnHcnAU/MppyNbPQW9/YMTxuRQwsq9veowQFprz9SNLC3xR6WHzA4TBtltoCNLfuoAGLORQaTEXsUFQ6FzTeVDPC5ULmiWLtrLTEmpnBMC/G9C9f6ZKHPp/pYKGxj9YfuCIhcVvo+YvdFz+oXFIdy2hAcc8WtDXzmxC3QTmbv8tksQUAJOQkJCQmHMQjorstn9H3XbX8vi/4jjOP3Ec5/9zHOefYbf/J068ylWh7vvz3/NYBcB+YoZUMMMNUVuS39jA/iOugsWV8dEGkswm+Maf91IZClKknMyyiab7YgGMbZhpcHPofQnA3FwYQI49g/72j5BpWYBs/RwCGLN+906+hFQv9kj19q/iZ+NmHvTaNgCz9WKZ7oe2TTZ/LqknhoGINg05MolqmIIwq4po2uJzJa1yGrIN7wInRHbtf9/1Rcpq650CND8sQMOwUsKU4sUHLtePMvhSpYfNDwrQci9Yh51X0BzGq30bhs6tXDnN62Ac57YBzKbWluob471ifP2bZZAlesViAcwy2DmiwhKAVU5Db3oVfvca4av6xSbUTm1C3aTA19eUAmASEhISv7x47jjOBwf7s/5jB8Hov3YcZz97DPWGnY15jb+n7v8du+1/V7fFGXr8Y3X/P7uNY/wvYvKfCID9tCQVjCzpuQV52y3cOLfdLqDqcGQSn1eq14hmXrHhw6FyL4t5gK2Xx7bJNTeksWVkcb0+fDNM8HH8OWQa5yHVuwzpjkV0TTw6FRzrnqeQTbyH9hsb0PQInfj8Q+OhTbwGMLMfzKa8mBBgKjamokIW5wSz6jn6MRzC4gCMXxvqWVKvSa6SmcZ56PHWsB+QlaP+vuuLD3Ruu41KWGOuqEGsfrQYgq+GYQVfOVS/Wu4XQkpt55V16OtbgUzTPJaLktuh0QtnVadMEI2bZRenMLHrWBLAzGtEzzFf21IaaX1N/nlM+GJW83Ew5u0dBO/EC+g+l4faabSfJ+VLAOzrSgEwCQkJiV9e/C8OghDlv+c4zl81HvPfq/t+G/Maf8eJql3/VN32V2Ke8w/U/RXbOEYBsB1IPniXO+CREtJ6pwC96VVUwZSturWUj2/yzR4UC2hEyg7Za5kbaCvIWMqt9OvbSsdoM6rMNrwTLyDT/AFSvcuQ6l2GTPMHLG3bP6xfx9s7CJmWBWi9i7OSmh4VA3t6XsJm6zmK6XPTx02fl2/OzTI5fl4t5XL6tRRM6d41Ewo4fNFQ6IOjCJsnX0J/6wIkz+eh8+p6AE3Xfn8A67y6rrPjOpYjNj/EvrDGHMJWw7ACr6EAvs4+VQB2LxgM3XF9Q6uQ6Y5F8Gpm8fip1NXSMxX6/Nyp0HQvLFVKyspZI9fLpnSy6xoHT3F9ZZFyQltpKh8szQHMSD1rb98QeNVvIHkhr1VHrUL+KAD2NaUAmISEhMQvN/6q4zhXHcf57xzH+Z8cx2lk9+02gMWFlCD+HkmwRfPAqP+Hw1jXpXUEFBqmbNtwurloX41ZKlgKpmwKF7/NVM74+3G1zSh15DBEZhpe9RsNX32pFehvXUDAJAWJNsEHRyHT/CFQwG4XUAkkmKFSS9eu2sUCGD9nbINtKmX6OQoUbCVrGgwOjAQzssxzRODFAEzPVKt9C6nkEiQv5nHoMoOm33dtkcsmKWutd7Cfq+VeAVruB9n8ENWxs09VPgmcD6kvseMaAli3vwap7mVUK6tmAhXMZkDi5gJVlvdWkQqqxg5YZ4aZ6hddK5uSZVPajGsbATAOYZb+RWtJo1l6GAdgf3wHlTC1hrMN76Dr8jpC7lAAvmLA8XWlAJiEhISExJ846Hb499htu12CGBcCYL9nmioYbZJb7wYlYF2X1yHduYibdgN4PDdXctDxdhUta7+OabNu9jPR5pqrGjxJHTrxAvpbFyDdsQj97R+hv/0jpDsWUU1RVvumQuHtGwK/agaydXNowtH8IawgHZlE17rDE1t/ZrOckl8Dm8Mj25xrBYsAwEwCRpqDRmCooIxcFPW/j0xi6WETll9q+FLZcW3jswBYy/3AUZHgq/UOuhn2pVYgWz8HXs0sXpeuJUj1LkOPtwadV9a1Jb4GsOt4TMmLeejtX4X+9o+oglVOh8tCzXJLMoU5MBKGeyrfpNlhZJJhQjQD41IqVex3gVKtx5AaZoEq3atoU5O58sUfTyqduR72DoJfNQPpjkXourwOzQ/CsLvbf3ckwykAJiEhISHhODiQGRzH2af+X0w4fsYZUsFIpWAQ1n5zA7rP5SHTOK+Bw6pEubloSWApAFOPtwKY+domfJGKwQGDIOPwBJaonXoF2YZ30N+6gGYbzR8gWz8H2fo5yLQsQKYF+9siJWhUsqicAv1jz/D1GNT5R6fwPtU3ZkJYKSjTn40gkow2uMqiNtdatSllw09W5kenArXHeA+/YiwYaF39BuHrQlB6qAHs+ucpQTz7tAjND5XSxdZS8mIeHSXVPDP/+HNUIKvf6OuS6l4OetJuBDPrui4pFSy5BNn6OewF4y6dZimsmwtgzFxj3LHTVBiZ4hqBYlupqPkDAS9xpFEGNLvNUjLLgSriJKrWhBW+YgxCvO8GcB2cfAnpriXovLKulcfmBwhhu/03RzKcAmASEhISEo7jOP+rg4Dkqv8XG/qfcWozjpsbkTIxKknsvIrKhVczG35+jMNfXMlcBEL4401lzHx9c4N7cNQOX5XTutRQK101swhSCkAyjfOQaZwP1A+beYbRg+W5al4TuQ+qeVwRl8IS5ZT6MymLef/YM1ThlNNkpJdtz9PY8k5+3J6bw2MhpYV/DjIeOTIJ3qlXkGmah+SFvDbJIIVJA9j13x/AGn5AO/mzTwJHQwKwbOJ9UP5HpiB0XqtmtPtk8iIDxKvrCGDn8tqMwzv1Kjj/pt2/2fNlrjF+bc3SVX4NS5hxREDM7Lejz3Z0CksmK6fxM6qevZAqppQsGghu3h/remj5ftE69WpmIdW7DJ1X1kPf6+YHX37QtmTpFACTkJCQ+GXEScdxvrPc/odOMIj577Db9zhYUvgpg5irHBnEXDYZAjDVm9P8MNg4t99EBSLdtaQ3tPr5W7nLxfUuxYBLXD+UtUSRNr2sv4nDV3/7R8g2vNOqgl85DV7NLGQa5yGbeB8t79uiVJIATw9DJmXDNAQxj5dvzqn87fhzyNbNBT12NlOIErDKVUbPzeljiRwDqXlVM5CtnwsUJuV42H5jQ6tgnwvAzvyIDoeJIYQwUsLab25AqntZz1wLPU/1rPkVY5Ctm4NUcgl6+1cheT4PXZcRwJIX8tCTYWYcNgDja9Fm1kLnlMOZAV8R5YuvD5trpZsLwxeVPqpxB97Jl1rlyza8A6/2Ld5OiiW7Rv6RyaA3zShVtLp82gDs0Dh4tW+hN70KHdeCHjwCsd3+eyMZTgEwCQkJiV9GTDmO8xcODlv+U8dxVh3H+TPHcf5HB8Hof3Ycp9p4zhXHcf7Swd6tv+E4zrrjOH9fPf5vOY7zB5b3+VHd/w8dx/lrDlrd/7m6rfAZPocA2GdKbT/P3OrOPgnKyFrvFKDj+gZ0+2u4uXNznw5htk0rf2wMhNmc5yJww9z9Mk3zWGLYNA9e9RsszVNlZ37VDGQT77Gnq/ZtaGZZ6Hj5QGU6ln1DqKIdf44AVjEWP3Sau+eZvUmqh8yrmYV05yL0pVa0C6N+HXUMIZXFLF/j58LNhcvWDADzD42Dd/o1pDsWoftcPjzv7WZg9f454Mtzc1A3iXbnZ8Y3oWEYjTWaHyIAJC/kQ7b/EVVp7yCen+o3eK1aFrQilryQh+5zeTTjqJsLA1gpEOPXhpch8jldFmUx1ireppiyOWu6X/DAiFb1vNq3kGmch3THIvSmV9EA5vRrLMc8/hz/WzkdLknlx2NRvWylvJ6bA//wBM5489aC/s47n2/QtuTnTQEwCQkJiV9G1DqO8684jvNfOQhHf+k4zj9y0Gzjg+M4e2Oe1+k4zt92HOf/chDg/lvHcaYdx/mjEu91ycHyxP/bwV6xv+s4zuPf9wOoEAD7TEkA1nJPWYUPYJIzXcv9wJAjMpyZp+FO+KkAZoOwUF+UWSZGqokqr8s2vMNer7q5YF6U6vHx9g9jCZ4qP/SPPw9MPOg4LO9Fx0nqmlf9Rpf78WHAseqXCQgHRvD5tW+hv/0jpHqX8TWpn4mdt9B5MOHA3IgT4KljCYHj0SnIJt5Db/8qdF5dDxlj6GHHVz8fgNVOBQN/z/y4GZQjPlQqWO+yHm9gvf77hlBtrJpBpej0a+hNr0K3vwa96dWgD+zo1E8DMDcX7g8zFa5SABY3u4uutQFiZNjinXgB2YZ3GoJ7+1ch3bUUqLTVbyKDt0PX3tKjFjrvDNb9o1OQaVmA5MW8Vrf5nL/d/nsjGU4BMAkJCQmJcgoBsM+Y7TdQAUt8H8xnasxhL09iEFWM9psb2At2+nXI3tsGT6XKECNwQq9jPsZm0kHlWmqWVTbxHnu9upZwcDSf10WfT6lfXvUbLP/i8MVmSenyP6MXyPtuAHu1at8GAFrC/dEKTWSY8d0A+MeeQbbhHW68T70Kjtl8TpwqaMBeCALMsslD45Ctn4OezKq2hDeNVtpufR7zDcra6c0gp1ANqx/FtdT0GAdbp5JLqCJajjlUJkjn+sAIgsypV+Cdfo1qJClgZp8drS36t0UV1ABWwubf2sNoc6LkPWL03mSoQb1cZDO/bwgyjfPortmyANm6OVwDldPWwdv8M9iuf+Q7cmBElx+Ss2XH9aDPc7f/zkhGUwBMQkJCQqKcQgDsM2fLvQIkBotQP4pJANbwA0JZ84MCJM/n0UGQ1AcDkGzQEVs+ZagXkRI+o8yQ26l7J15Atn5OW8xnWhYQsPjGm5zoyPDi5EvtwBdRS9zSM8y8mtmgdydOpYjbrLNz4B8aB69mFjfeJ1+G+79iytys/XGllBF2v181A/3tH6Hr0rouRbMB2OdcRyEA4xA2gmuq5X4Bus/lgzVknEuu3nE49txc2LTj8IR+rvU8sWOKABi79rZrFwF/eh8OZeYatymzewe1kQb19ZGqp8FLGcrYSmJLXntL+kcmIdP8AbrPsQHbAmBfdQqASUhISEiUUwiA7UAmhorYwzOJpWONOQSw+hGEsa7LzBGRDSOObArjAMyEBVvZotlbQ5tu5nbonXypDTUyzR9wM1sxFlVByHGQLOVN6/ISSgkvBSQLew6eW6pSxmBf7+Co7m3yqt/YzTdihv2GAIMfr3FeI4rI6dfQl1qBjuvGQOR7gcnK515DNgCrncJyxIZhLEdsv7GB15D1vvHP5bm5oL9v/3BY5eN27fT4OMVUvabtNr0GXIvDpO3xpjrnGjPk+DGSYrd3MFy6uEcNBqcxBqoMMuLMaKigcaqwuUb8488h3bUEXZfWBcDKJAXAJCQkJCTKKQTAdiATg0W9cU4MYi9Y4nsEsDPjm2jGcS4P/e0fsayP9VBFNoZbJYcwtvkMgQY3NlCqhV8xhmWEJ18GRgYVY0G/l1niSHPDDk8EG14LzISOn9mDe/uH0Tmxfi4ETSXVCROm9jzVfUBe7dtI+dx2ACykiLDjtp1T+m+mcR6S5/PocmkBsJ1YQ3EAVje5qZXVlnsF0EYo9FxLPxfNegsBppsL9XBtB8Bir5d631j4sr2GKonUrpPmkOb9w2jUYhteTveTHT2Hq20osaXS+24AvJpZ6E2vQtdlAbBySQEwCQkJCYlyCgGwHcra6U2oeYZqBRlyNAwXoW5iE1ruF6Dr8jr09q+imx03j9jmRtG6wbWVormGMkGmGMre26+cDs1NCj3f/FzU62VRFyLHzlWNPU/BPzyhXRVNl7rIe9HrcTMPUkVqZhHATrwI9dBFAMw2aDeuj069RlyJJw3jbbsVtSPfSUvyOAA7M4bKavODAmSa5gOgpTXAy0JVGZ9/ZDJ6vplqGrrmJcoQzWvPz1NJ5cv2umbfIF1n5jrpnX4drEvzNVjvYQQeS5SUlvw+ubmg/PCKAFi5pACYhISEhEQ5hQDYDmb1C7QRb8yhcULT46JWxxpzRW1Ln2lZAL9yOh4StlKKbIYGtrLFPU8DRYRmJVl60PRnsGxmIypTnLMdwRcBmLK314qfZSMfKQljEOe5OW2tHhre7ObC6p+bszvwcSXELDek1+CfeU8wDyp5MR+BL8qdXkNWCJvYhMQQOiL29a2ALuskhZOplnpmmlI36TPy99hW6SBXlmJ65qy3sx60kuuVD84+OAre6deQrZ/DMl2LS2YEIumz2F7zNw+2BWDed2i40ttvqF8MwHb7b4qkPQXAJCQkJCTKKQTAdjBrnqk+sEEFYI+wd6fmOd7e/KAAXZfWoa9vBZUh2sTGbYLj4MuErpgyPO2Ed2g82jvFNsahDTUrI7QCmE1xMjbXnptD18LEe4QnNxc+9lIllqSKHBwN5jyZZZJuLgRhoU0+L2tTj7WalNBr8PO8dxD848/D6tedwHr+S6yh2plNqJ1BNbV2BkGsbnITGn7ANdXtr+E8rFOvwmDKXQRpqDF3ttyGKhQ5HhtAmWBrlhISPMVdW2P9eN8NaMv/TOM8lsjSNTVf23K+QgDP1+92lGR1vZPn82H4IgAT9eurTQEwCQkJCYlyCgGwHU4qQ6QZTs0PC1A7tQk1z9HRrv2mUsGaP0TKwfjGMFaB2Aq+ePkeqSI05NbcfNs2yNwcwXa7mQZQed8N4HudfImQeWDE/l62z8PA0T8yia9Bz7eVuNnmpzHrenpcyTI5N6dv8w+NQ6ZxXg9Y5nOgvpQaUvMM4avmOYOwKVw7TY+LkDyfx5leifeoLhKcurnAgMNMyzqL7S20QX9MiZ95/QjAYqHd5kS+IwAAIABJREFU8kOBt3cQvBMvsF8w8R6BW5WjZn59H50QvzWcDY1rZ4VCm9LKP6Obwz65+rmI+YbA19efAmASEhISEuUUAmA7nDXP0TTh7NMAwBqGi3pjffZJEbourUOqezkyw0hvJt1cVN2JgyDbptbNhXuDjLKwyMbaVLVKlBfqTbH5/qwEzT8yiXOnqmbAc2PUEBPueD/Q4YnAMERt9GP71NRnsqox7PPGbuDpXKkyuL6+FSxHuxLekH/OmV+l1k4kn6EKpgHsQh5Svcs4GJv6vOjzktGFUsD8I5OofNp65yzXoiSAWSAmojrSjwbmWuX/b8L2gRF0uWx4h/1fB0cD+PrVPV2Oyo97WyW6pZQvUr/UuIHItRYA++pTAExCQkJCopxCAGyHs/olKhaNOSxBbH5YgMYB7AM7PYuKRtvtAvR4a4Gltq0fiaCJNrpxCpRFRfLcXBTA4krR+GvHKBUcukLwxZ6jN7WHxhGeTr9GhcFWemgrXfz2cdCvpuDLP/Ysuuk2zzn/LDYnRFvpIT2PztOBEbQi71iE7nN56Lq0jqlArPPK+hdZOxy8ql9YAOwRjjToTa9CNvE+OL/8uisA8w+NB6YrxvBmq5JaAloi8GIDOfXDwacopp6bQ0OY6jfg1cwG5aYM9rN7nmrnxghg26C6VIklf+zBUfBqZqEvtYLq1/WNUAni557zJvl5UwBMQkJCQqKcQgDsC2T1CzRNaHqMznVNj3AuWPVLhLCG4SJu6hWkhACMNrPbATClGoU21NT7RVb05BwXN7srri/LYmwQq76xzb9fNYO9W8efg+fm7Jt9Q2ULwdvRKfCPP8e0OfnxjOuPM9U1BgiR3D8MfuU0ZJrmoSezCsmLDMAYhO30mjFLD00FrOEHhPmO6xsIYPVzYQAjQwvq+SMIPv48HsBiVKntwJcNwELHsp0eRZr7deIFwuKhcVwzBqzFAXYcgJVS8kz1q/tcPqRyUu723xDJ0ikAJiEhISFRTiEA9oWybnITGgcQwFruIYTVjxTh9OwmnJzHAbup5BJ4p16FSsR4KV8sgMVtQll5VZzyZTVVcHNb95zFgZd6Xf/IJG72jz0L+s0ssBWBRTcX7l0iaCRlsFTpoO1zmZt9DmDG6/gVY+DVvoWezCq030TVo+P6hla9yJa88+rOAhgZb/AkIKudUS6IgwhgXZfW0UXz2LOQvT/1SvmHxiHTNA99qRVId0XXV6kSRGuvl+k+SWuLrVfrmrG9prneDo7iNaCyyYOjwQBpG7TxNcd/ZOC9gGavn6GIeW4O/Mpp6G9dQPONK4b6Je6HZZECYBISEhIS5RQCYF8oa6cC6/CWewVouV+As0+KUDuzCSc/bMLpt5vQfS4P2imQwwa9Du+zsZleGBvNEIDxpNeKM1+wDLONmHXYjD7ovfcN6ZJBDV9GT1bcht9zc+FNPc9Pga9S5ZSGsqPPUc0s9PavQtutDWi5p6zm7xRw/tONYA7UTpajkdNh7XQUwui+M2NY0tr8sAB9qRV0QKwYi1jxe24OvJMvoa9vBc06upexj85i6x4LYAashFwWTej5hNcMlXzy11E/MmjDGBrUbCmtjYAhgRuDdZtiF/pMB0aAD17WvV8KwNpvSPlhOaQAmISEhIREOYUA2BfMM2Ob0PS4qAf4ttwvQMMPRTj1bhNOfNyEtlsbqIKdfImbSOP5oU1tqY2om4vCSqmSQwsEmf1SVhXBBn7KNMM7+RINFLgCUgrAzI25cZwlwYt93ggkxrgzmgDmV4xBX98KdFxHu3kNYHcD2/m22/jvnVofIfiKyyk0dWkcKELL/QJkE+/xfFuGFfuHJyDb8A4B7CK6Jeo5bK4FsI1rYlVS+TFzV02bCmZ7bRO+LMqsvi70+q5lbIEJ0G4Oy0crxgIIY5/RWn7oovqV7liE5MV8xGRFzDfKJwXAJCQkJCTKKQTAvmCeGccyRA1g9wpw9ik6Ip6cx7Ky7nN5yDa8C+Z00fNjygWtaoKx2bT1xMTCV1wvD++ZMlUEDl8VY7p/J6RAxYGjZaNv3bDbQJKnufHnAEa9cfw+A768mlnouoTzvgi0CJKbHxS0g+VOrQ0+56tU1k1iz2DT4yK039gIAVXomqteNu/UK+hvXYDe/lVIdy6i0Uucwlmqp0qdf6vqxAGMHUds3xVdR9MUxlIeyB07S6lz+vE088wGYObxHRiBbN0c9HhrgfHGdXE/LMcUAJOQkJCQKKcQAPvC2TAc9IHpXrDRIpx+uwm/e70JrXcLkO5aQtMEpoLFwUNETYjZ/Hpuzq4SxW1qSyhUcfDlHRxFlz0y3OA9VyaA8Y2+eWyG0mEtVzPs9GMVF6M/zdyw+4fGIVs3B6neZSw3U/DVehfBq+lxERJDRWgYRuOUnVgTvL8rFsKo/PBHLD9svYvOmXqNmJCzf1g7H2YT7yHdsQj97R9D5a2Ra2qDXhNsTXMX6tWylYzGZQlHzsjaIhWMX+e48lXeC1ZKCVb3+VUzkO5cxNJDga+yTgEwCQkJCYlyCgGwL5xnxjaDPrB7BW1LXze5CafeYX9P8kIevNq3Ibe6yMbU3FjyOWFxj6GMU8C2CWGx5V8Kvvwjk/bnxUARHVNJADM37VT6pjb/5jGFXsdWtuai5Xk28R77fy6tQ+tdpXg9RDBuHED4qp3C0r/PvRZsBhslcypwP+y6vI7Du81zZ5Tv+RVj4B9/DpnmD5BpmsdyxZj+qIiaFFfWyeZ8+RVjQf/ZVp/ZBtDmkPGYtRWZg7dVD6HR72g7lmz9HHT7a7rXq/2GAFi5pgCYhISEhEQ5hQDYLiQNZdYlbg8LkPgee8FOzW3CmXGEsGz9XNT5bxs9NpGSKzcXKCJHJgNoKbGRtZZ3xShoVMbnH5kMz/oy1JQt1QvzcXQ7wRZtxGnjvn8YhzQfmQwdH//cNuXQrxiDbP0c9GRWsedLgVfjQBESg+hOeeZHBJ6aZzsLXjYI0xb07Dbq+2q9o5SvmlmEKfW5QyWXHGz3D+P5qX2LDohkamFeW5tzoLotAsV0bfYNBQBGx2EDKHp9U7mMM4axPZflttaR+Z58fag+xeSFvDZWab/JAOyaOB+WWwqASUhISEiUUwiA7UImBtVMsIdBf1FjrgjVr1AF+90bVMlSyaXAMtzNxQOYrZ/KfN8DIwhIR6ewv8xQjWwQF9qgmyYLfNOrNrT+4Ymwax3fSBMklAC+SBkdV0BYXw8/F7oMLk4V5MdM6lhdAF8t91SZ4fdYYlg/WoS6CYQvKv37nNd+S5XLZjuvRhi03i1A8kIelayjUyHb+QiA0ec/OIoAdvIl9ovx68NVIwNUst8+jo4+YL10dF206YVlXejHubmo+mU6c9pGDNgeEwdgcT88mACmvgte9RutclFy843d/hsh+WkpACYhISEhUU4hALYL2fADqhkEYU2Pi9CYQ0v6028xz4xvQueVddxoM5tvK4TFGVrQezJQ8Q9PaKjbDoB5bi68ETfVL/a6uhTNAlGR149RLkxlLfT+cT1u6jOG3pN6h5iq432Hxgu9/QF8nX2C4FU7jfO16iY3dcnh5y47PDOmXp/1dMVazivHwzM/Ytlh6x0FX80f0FyDA6l5XZQ6pa/L0Sk0RuHXnilanpsLz1pzmY09f32+vrj6dXA0FopC5yAGqCJKmO2x7HVs6ycCfPx1OIDtHQT/yCT0ty6E4EsArLxTAExCQkJCopxCAGyXMjFUhLNPEcLOPkEFpm5yE6pfbsLp2U2ofoEqmFczqxWrOLOCSNkXBw5TEbI5ym2lJsQZXezBOUoh6++YAbhmGWCs4sZhks6XUR63ZTmmRbXTm+/jz6HjGlrNNz8sQMMw9nhVv0A4Igirm/y88EW9fg0/FOHMOL5PnM183QQCeP0IlkSefYLumBq+jGHDVug+OKpLTv3KaXweu0bZPU9DvVzaTIMpTOZ5Dr2PCWDbKC2NXE/bTDFbmueTq6m2kkebXT47L17tW+jx1sIAdiOY/bXbfxskPz0FwCQkJCQkyikEwHYp60cQuhoHUP1qGFZ9RzMIYdUvcHBzunMRXQUtVt+l4Mt6n3puCHTMgco298GY1/W+Gwhsv2PmjJU6XrOsLaLk8XNmbLpLKoHG+aDX8g9PQKb5gx60fPZpEc6MBeWGZ8ZU/vh54av9JrorkutlYw7NPc6M43uFcgwVr8T3Rd0r2Ha7AJlGVXYYZ/fu5sIgc3A06Ms7OhW4H3LDCzrXB0YQ8g+O4n3sutiURs/NxQNYjOlJpDzQNk7ABl82Vcy1z/fSyqdFNdPHfPw5pJJL0Hl13QpfAmDlmQJgEhISEhLlFAJgu5i02abeozM/hhWYMz9uQvuNDehLrYBX/QY3yUY54nbgy7ZZDQGQDcDMUkHzdfYNhUsZTTAy+9HiAGyrY9xKMYspXwyB2N5B8I89g3TXEnRdXofmhwU02lAqU8PwztrMhwY639rQs8ZCc8Ye4L9b7iFwdV5dh25/DdJdS5Ctn9PnMLYE04AvfR/N6do/HD1/6v81oH03EJmdVup9/IoxXJMHRsLrKW7NlFJn+WvbFCxTIbOda1ufmbqPZr31ZFZx3MCtALw6r67rFAArzxQAk5CQkJAopxAA2+XUqgtTQ+omgjK0lnsF6Lq0DukOpYTxmUu2vicDXGyQFgs5W5QlhkoSaWPPwccCgtuBxNA54ccWAwy2/w+ZUZjHfXAUson32nK8MafUp7FNVCFzWOq3E9e3+aECKwVXBGFm/xGBWfuNDUheyEOqexmyDe/AO/EC4SGm581zc2FwYWAcAjDmeqmvgYIl//AEghQBmMqI8kVrTI0B8A+Nh5WzOBUy5vpaAcz2mFIGHvy55nng/3/yJaS6l6HjWnCuO64r+LoSANhu/z2Q/GkpACYhISEhUU4hALbLGSpDG2cwNo7W480PC9B+cwN6vDXIJt4HphxuLtKTE2dSEadEWB9jM8kgNYtv8GlT/wllkLHKnJuz25GbMMXVFaPcLdLbxCDCr5qBVHIJui6tQ/uNDUgMoeKYGET4asxhyd9OXN+mR0U9aoBGD+jN/5Xw5r/zyjoabbQsgHfqVaB48mvN/h0LYNwtkq7V3uiMOPq3Bik3F73m9Dr0eA5g5HwZ86NABK7Za0XAzLyPK2V0XynTDtt5IAjbNwSZlgVIXsyHYFerX1dE/Sr3FACTkJCQkCinEAD7CrJ2SpUcjmFJHCUN3W27XYDOK+uQ6l7GjTmbu6Q3qORix2//KWWJXLUy3ez4Bp82tzZFy1DFtg1gdE7M97eVSRolkxoy+ON/8wBL7xreQU9mFbour0PrnYIuOST4asztDHx5LgKYHvD8AEsR22/ixr/rMmbnFfxv8kIeUr3LaBfPyju3VJE4cPB1YKwLa2/f3sEAwAyLd/6+kWtlAzCbKYipoNmUL3Z/7Bqlx8WVGZYw8vArxkKlhxEAE/gq+xQAk5CQkJAopxAA+0qSTCCoJ6zhB4SE5gcIYB3XN9AJr2UBHe3MX/+3qYCZSpdZ0hZSSLayE1fP+2TFK24jbh7zduCLepW4uyP1Mf3mAfjHnkEquQTJ83nouL6BQ6+HFHgN7DyAnX2CFvKUdC0Jurour0PXpXVInldlh3VzEXv5yDk3zxfdbwIYL9+j8kLTnTDGATFy3c33OjASABgZxFhKCGP7v/hn2u6PBOb6s5UlmgC2fxj848+h8+p6CL4IgqX08OeRAmASEhISEuUUAmBfSdZOB2WHBF+JQQVgrGStN70KXu3baP+Labm+VZkh32AbapYVwGwlY5YSta36vmKBK86S3oQtMogwzSLcXPg5dF/iPapfl3AD3vQYwevsE5VPdw6+PDeHA5QVeLXdRvWr4xoDsEvr0H0uj0O3a9+iGQZ/DaU2xRlPhNQqozcvomBZTFY8Nxd6/Qig0zGYahvZ3HNjGIsCtqWiVWLtbAvCbH1hHL6OTkGm+UOo9JB67UT9+vmkAJiEhISERDmFANhXlGd+DACM+pNa7hdCQ2IJwvyKseiG081F1YUtFIYIRMX1/rD/31byzxbX82OWGtp6vkolQVZcX9jBUej216DrMvZ+NT8o6Nlr1JO109e0YRhLEAmi6RpSv1e6awm8U6+0AhUBHd7bRteLmUyEgPNbNTuNhjRzMLFcuy1VJ4I//lr7h4MBz3z4tvkexrXfDoBt99isQGau/YOj4J16BanuZei8sh4CL30dRPn62aQAmISEhIREOYUA2FeUtVPhAbwEYKHN+1UsV/OrZuI32Vw1iVOXYkoCQ5tvDgR0nD8FwOh5xv+XhK/tlh+aAEaKkJsD//hzSF7M6w1406NgtlbL/Z2HL8/Fgdsh4w0yfbiyDr39q1hyqGzjrT1x7DyF4IsAjJQtBaOem0NAqpzGGWA2I48SIGYrNeRW9n7FGIIXWdfz/i/b7K1trg1TbbMdU2z5LH8fN4fHWTUD/e0f0XjjRlB2KDO/fp4pACYhISEhUU4hAPaVZd2E6gUbRme+lvuqdI1tHDuvrEO2bi6qPri5CICZJYc/uS+L/3s78GVzqrNt+uPs7gkc4yDL0gcW+jwHRiDb8A5NLq6i+QaVHDY/QDfCL3E9E4OBkQoHsK7L65DuWgL/2DN9bkJQYQMON2edccXPh7d3EPyqGcg0zmNJY+W0Nm2JU6Ai15/uU0oSDVz2D40jeFXNaMCL/Ahgc7O0gZ2lh5Cvk1I/EJQsZ907CP7hCcgm3kP3Oez7Cw1cvi7w9XNMATAJCQkJiXIKAbCvLGn+V/0oM+G4Ff3lPt21hHPBaOaTmws2ocypsKTKtM0NuRXQtgtfMWYdkU01U66ozI2OJXLMNggzNuZ+5TSku5ag80q4/LBxAM/pl7qeiUHsNWu9GwWwbOK9nr9lVaXixgAYyiSHNL9iDDKN89CXWoH+9o/gnX6Nc9CMHrAQqNPxmtftwAhC15FJ8I89w/V24gX4x58jhJn9X0bZ65YAZqhdcefB/BEgpBSaeWAEvNOvoS+1Ah3Xghlrpvol5Yc/rxQAk5CQkJAopxAA+wqT5oCdGdtE9eRW+Jf7jmsb0O2vQaZxHlUI7n7o5iKmHNvqp+HHsFV5mq2ULE7h4MdgM/WwABiVuOnNfdxnsMBkdo9yRKyZhd7+Vei4tqHVr8YBBWBfoPeLMtTLdyMAsOTFPHjVb/AzligJjFwjm9EFh9dTr6C3fxWS51V/2YkX4Lm5kDOkNi45MILq2MHRoNeLkkw2jkwieFW/gWz9HBrAnHyJQKas6/Xn5YBorCN9/GQUwo1FbLBmrB1+W6RMlqV/7BmkOxax788YcM3LeAXAfl4pACYhISEhUU4hAPaVJg1oJhc9E8DIjCNbN6eH6FrByM1FNvIljQz465SCsLjnuDk7fMUBmBtWubzvBhDAKqcj9uYlQZI//8gk9v9cwP6flvsBgO2066GZie+LkBgqQtOjYmj+V/JiHssPDaDabp+e7Zxq9atvBV0V1cy4UJ8YpRpe7R+eQJg6OqVdDf1D43j7kUnsNax+A9nEe+hvXdCljd7Jl2hBbypoZomkDb5YT5m1XJFeiztzsttiAWzfEGQb3kG3v4Z9X7cD90mtPgp8/SxTAExCQkJCopxCAOwrzrqJTaib2ITGXDE0OJaXUSUvMqWDlyOWcL8rWS74E1zz4srGSoKDCYRGCaJ/aNw+3Ffdrwcv02spVcc/PAH97R+182HrnYI23yAHxC95DRtzOFT77FO8hlwB8w9P6PNsBVR+O/+veQ5dVA29U69QVTvxwmrOEnGJVLCbrZ+DTPMH6G//CJmmefBqZsE7+RK8068h2/AO0p2L0OOtQfJiHpIX8tDbvwr9rQvYY1Y1gyoaARXvCSPgYn1kGqq3A2pcHYyxuddreN8Q+JXTetxA2+1g7hq3nN/t77TkzqQAmISEhIREOYUA2Fec9SNFqJvEUsSmR8XQr/gd14OSquSFPPS3f8RSMXNzW6oczKIgmNATp7aEbjOUtVjI2uL+UJ+TAqyIYrd/GJWZyunAPZDgbe8geKdeQU9mFc0XCMAeB+WHuwZgTxhEE4Ax5dLa82VCmM2wRJlOeCdfouJFpZsWRdJWtukdHIVM8wdIdy1BXwqVs0zLAmQb3kGmZQHSXUvQ7a/pfiqaY9aTYRB27FlQysgULu2YeHgCPyuVOpYyaKHjtcG3BeppzRBIkvKlB19z90kBsJ9tCoBJSEhISJRTCIB95Vk3iSpYYkgZOZAKRgBGEHY+jxtisgXn6oLNHty8nQMY3/TH2LzH9V/FqWMlH8OPYSsnPaWO+Uen0OmQjnHPU/APjUOmZUFbj7ffxM1406MAwL709dsugEVKNW1lmrayQxO+yHjF7KWic2na9e8fhv72j9DXtwLd5/LQfS4PfakVSHcuQm//qnYSbL2L1v0t99FBsuP6BvR4a2j0QW6LRyYD4FLli/7RKTzGUvDFzkFkHRhrwPq59g+Dd/IlpJJLUfXrZgBgu/1dlty5FACTkJCQkCinEAD7yvPM+CaqYOPYD0b9LJG8tgHd5/KogpmzmUyr+rikPhoOXyVmbX3qfLHYx5iqXakeNHJ4VCqPBol9Q+Cdfq2NN0itabtdgOYHBWjMoRnGl75+jQM4WJsALNQDZvbumSoPzeFSjpARs4q9g1hueOoVKoL82sWUhkaUtn1DkO5YhFTvMnSfy0PX5XXourQOPd4adF5VZZx38Rw2PQoGWLfcVxCWWdXqq185reeD+VUz6JhYOR2oX3Hr0PzcfD3ayg55SeK+IfCPTkGm+QMkL+TD6hcDsN3+HkvubAqASUhISEiUUwiAfeWZGCoihKn5YE2Pi9rVTTu7XQ8stvvbP+LGt2Is2pNjvn6MocYnwZfpQEivZ752iR4wXbrG1bcYgIt7Pb9yGtKd6H5Hzndtt7AEsflBYVfUL89FAEsMMhMOZUGfvJBHB8sS14H3UOn/sn+T+uVXzQT9f1uojSaEeW4uADBlXkFlhq13UO0i+Gp6zPIRKrKdV9ehJ7MKXs1sGMJMAKPryz/fdnsU+eO5qrtvCNd57VsE7+th4w0+vmG3v8eSO5sCYBISEhIS5RQCYGWSiUFUUhqGA0MHczYYwVi3vwaZ5g+4Ia4Ys250Y8sEbUOOeSliXD9SHIyxeVJx1vjkehhRhGzDemM26jTzq/UuKjTNDwq6bO5L933xPPsEgaX1rjKDuMIUsMpp8FyLu6NFVfTcnJ7bpQciH3uGEBZn/c6PxVSO6PFKAevJrOLAal5qqJJULw1hjzCbH+D9GsS8NUh3LUGmaR4yjfOQbXgX2NVzR8tSpab8s1MvHHdOZAYfpHx1n8uHer/04HIpPfzFpACYhISEhEQ5hQBYGWXjQBES36u5UvcKWqkgZ73Oq+va6rw3vYob4KNT+HxbOZrNUIMnV784jJnlg+RGaPYXUc+W6gmKHcp8YARL6U68CMrt3FxUMaHbTNjYP4zqzc0NaH5Y0I6HBA27UXpIefapUovuFDQwd17BMj//+POwk6MNwPi5pM+v1C//yGTEyt1ayqfuC4EcpeoBo/I9gq3mB6h+tdzHf4cgjADsYfi+1jsIYt3n0Ckx1b2M5ZFHJoMesBImMdaB22bZqXqef2gcsnVzuuSU1E6z76vzigDYLyEFwCQkJCQkyikEwMoomx8gXDQOBCVgelOvXN6oNLHr8jpugKvfxPbRxJWlWYHMADDPzaGyxWZBmQqa5+bQCU+ZM8Qdg7dvCJWSY89wo16qX81iMOJXTkPX5XUcuPwUVcKG4aK2n08M7h6ANQ7gEGYOBh3X8Pp4p1+Hh2jbrotpyMEBrGIMb4t5vs3EQ6tgBDUHRiDdsQjtNzaw1FApXC33g2HVNhALwdhjZfP/BFWxttsFPSw82/AOlVgy4uAzwAyYLmnSYqpmp19DqncZOq8EtvN0jvl3Yre/s5JfJgXAJCQkJCTKKQTAyiybHxR0WVvzQyz/IqttKkOkDWjyQh7SnYsREwerux4HJ9qkxxk3uDmEgCOTQWkhVzBozhQ3keADdE0AU4qGhrm4fjU3F9mI+4cnIJt4rwEi8X0R6kfReZDs53fzetEgbTIF4aVx2bq5YJCxeU1Mu3j67Ap6/cMT6AJpKGZb9tDxstCKMfAPjUO6a0mrh6RscQDzXAPCHrC+sEcIXqQ6nn2iAE45Jaa7liBbP6chTM8CozED7PqW6lkLXfuDo5DuWISuS6j4CoBJCoBJSEhISJRTCICVafKNMkEYN+Xg9vTeyZdhtcTNxfffKOVKKxQmhKmSQf/wBJY3mjPDzJI5PoMqpu/Mc3OBImObDWXra1Ibca9mFvr6VrTbYeJ7hC9yHtzt69Q4UNRQwAGs49oGZBPvw3CsnhMLYMp0wj80juC7f9jaf2eFXMNBUCuTldOQ6l1GAGMKlwlgnpvDHivWI8bNOc4+CWfTY4Swbn8N0h2LwbwwBY4RY5jtAtiBEfCrZnA22fXAbEWbbjCVcbevveSXSwEwCQkJCYlyCgGwMk1SIWguEw2dpQ0+3+inOxaxF4cMOXgJmpuLwpObC1nCRzbCSj2hQchWQOIAwGZ1lQQE/hnjXpP+vX8YvBMvIN25CMnzeewBuotAkPh+d4Yu27JxoKjLQnl2XN+ATMtC2HiEfc6IssVVK3K4dHNRUNvCaEUbeZBV/MmX0Ne3Au03N0KGG80PogDmuTm0eDcgzDTp4BBGpYj97R/BO/06GBT9qQBGn79yGrIN73S/I1e/+Prf7esu+WVTAExCQkJCopxCAKyMk+Ydtd4NklQAXorVdXkdkufzkOpdhkzjPMIYWZdbTCC26hcLlQHaSgPdnFazsnueRvvHuBufxXzBqtzQ594/DH7VDGSa5qHHW4Ouy+s494sDzs0gd/saJb4PAIzUGrouqd5lNOKIcwfk5hqqXyt0Xj91JpubC3rIjk7he1e/gZ7MqgYw7nS4nc8XArEHAZDx1yGXxL4Mq+MhAAAfWElEQVS+Fcgm3kdLTWPgK3TtD46Cd+oVpLqjfV+8/FCUr19mCoBJSEhISJRTCICVefLBs613AxtuvtHn1uc9mVW0Cm+cDyzMSxkgxKkpbi4KR5Tkjmiac2wHwGLUHHptv3Iason30Nu/Cl2X0XhEW/AbjpC7fW08F8cH8KHQZJFOTpXe6dcBjJAySaBFt/PzWeqclQCxkPpF5YfHnoFX+xaSF/M4L81wOdzuZwwpYaUg7Aoaw/hHJoMesO1AmJsD/8gkZJrmIXk+sJy3DV3e7estuTspACYhISEhUU4hAPYzyNBmlJQwBmEEYF2X0f48eR5twr3qN7gZtvV62TbyMWVukfI5KmMkswU3F36+m4u3r2dqWQi+VAlaNvEeetOr0HUpDF8EXvQZuy5/JQA2VNTXhPfrdVzbgJ7MKhpxkPMjBzCmdoWA1bX0iJUAsBDEqtf2K8awh+/YM8jWz0H7DaZ+MYv5T/mcIYdEE8CUYUz7jQ3o61sJAMwoQ4wFMOr1S61oy/nQemflt7t9vSV3JwXAJCQkJCTKKQTAfiYZgTCmCoTg5HKghqW6l4NhudQfZikJjLggmqYbBFUq9WPIMt41AIxAg5c/mgBGboxuTrskeidfQm96FZIX89B5xVC+OHxd+jrgy3OxBLHlXgAkzQ/w2nRc34Duc3kcmH14IgxgzGqfzo0+t6Xgq1QpqZsLyhgPjiKEqX4qGl4dmu/1+wCYObhZqWBttwvQl1rRBiKlZoLx9I8/h3Qnuh7SvK/Wu2pOGet/lPLDX24KgElISEhIlFMIgP2M0izLIgiLKEQMwnr7VwOXuqoZbawRUSNsypTpYkiwZYMym6Odm4sHMKai+ZXTkK2bg3TXkoYvrX5dC/rcvjb48lwcxBwHYMkLCMH+8edWINHnhZwp3e0BmNUYRZUfEoRpAEu8h5Z7Bnw9sLsglkpeehgHYK13EMC8g6Nh6LJBGOXeQcg0zkP3OSw9NOGLAEzUr192CoBJSEhISJRTCID9zNLWG0N9R6EeKQUxnVewJLGvbwUyLQsIYtwq3M0FAGYoYJENPndN5Fb0bs5qhx4pbzRUNv/oFHjVbyDTsgB9qRXoPpfHvi8DwDqvBlC52+fflgRgemyAAgbqycvWzaECaUCIOdSan8e482Y1sKDXNAGsagYyjfM7BmAcwmhmXW96VZel6owzH1HKZ2//KpYe3g5KbOkYqaRzt6+x5O6mAJiEhISERDmFANjPNLkboOkWxw06ImV8l9ahx1uDvr4VSHcuQqZpHryaWZw9RRboZKBgm9MVZ0vP06bMEBQcmQTvxAvINryD3vQqdJ/LQ/JCXqtbBFoaIK8GMLbb5zwuuWrD+5U6r6hS0N5l8E6+tI8FIDXQnJNmjA6wGpi4ucD1UM0Oo4HXfuU0eKdeQX/rggYaE54+5TNa3RCpF4yXIPatRAGMrwv69/5hLD3sWNRrmFvgNz8Q+JIMUgBMQkJCQqKcQgDsZ54EYua8JG1Xb8ym4uV8yfN5hLHUCmSa5iFbPwde9RvwTrxAG3PqG3NzUdjiigtP3oN0eEIDl3f6NWTr5iDTNA/pzkWteCUv5CF5sTSAfc3w5bm5EEBEzFEU8GYa5/F8WhwOtREFA9+IAhZjOa/P8+GJAMBoBlj1G+hvXYC2W8YMsJ8CYPeC2WD83wRgzQ+x7DKVXAoALG7O274h8CunIdP8IZjxxiCW1C+BL0lKATAJCQkJiXIKAbBfQNJgZgIvnQQDJojxsr5LgX19X9/K/9/e3QZZVhZ2Av+rJL7Vmkw0GijJDioIQgp5Heel572nBxiIiCi4lii4L25GARHFAaEHBueFYbEqi5XdItk15VY+aJX5ortbZlNaamqNJmajazTRZHZRoxGMLBDREM9+eM69fe7te3umZ1qmn+7fr+pfzJxzz+17n7na/e/nnOc0myf2NFvW3NVMXjA9s4DHr94w80N+W6q2n/LOZvtL31XykpvKkuen3txMvfw9zdSZu5ptZ9/WbDvn9mby/DuaravvbLas29Ns2vT+ZsPkzKxXP70CdtnsAtabwTveYzzf8e8tRb/usgPlWrCJPeVasF/6l7NPJVxxXSlgvdUSR1yjNzCjuOK6wfJ18vXlvyf+xqwCNnnh7ALWPRXxSN9jf4bv6s41Wr3nfGMpnhOXlEVHxhaw3uv+1RuayfPvaNZv3zfruq/erNqrXj+/gihLOwoYADVRwJZJBmbCxpWwNr2ZsP41Y5e3ReyS/c36i8qs2IbJvWUBj7V3NVtX7W4mL5huJs+/YzAXTDeTF+5utq7a3WxdfWezeWJPs3nj3c3GLXubDVP7mvUXleebuLhTtNpy1St+ve29fcMF7HiP65GkVxSHb8bcXxilnQXbds7tzfaTds5esOQF/6p/CmjvurxR19QNLGjxwrfNKl8DM48rb2ymTr+lmbxwd7kH2BsHl6HvLRhypCVs+Ibg3RL2qtcfbNZd2t6I+ezbRp/C2nufJ19fFt3Yvq9Zc0UZq2756pVDs1/SjQIGQE0UsGWUbsnqXiM2fIpib/+sIja01HtvJcWJS/Y367fv66db0DZMzpStdZeW51hzxeDrGC57/cVBdgzNgl02uIDI8R7PI033Wrv+uLenIPZvkn1Jey3Y6beMXD6+V6D65WXFdbOvt+sVsN7NljunHvaP7V0P1hawravv7BewWUvRd67lOtx77K682V2l8FWvK6e09k5jnTr9loEFXgZusv2rNzTbzrm92TC1b+Z+X6+7Z6B8nX/NvfNeIESWfhQwAGqigC3z9IvWFTOnIA6cKtedFbtidpHolrRR6a+6ePlM8Ro+Fa//3FcMHtOd+aqtdI0a5+HMukF2e6rn9pfcNFNSeuldQzfXfbNWXDfz2LZs9YtXJ70l6KdOv6XZump3s+aKcprfqOvAuiXswjeMLz69z83wzcA3TO1rtqy5q9xw+rR3l5Utu++tnambevl7mvUX7Z81U7jqqlK8znvzzFL2x/vfUhZfFDAAaqKAST+9EjSwYMeIUxS7JWpgNcXXjClTlw8WsO7s1/BKhgOzbhXOdo1Lbwy74zM8ozixo5yOOXnBdLlGq1tUhgtYt4j1vk534ZNR5a0tZN0ZsMkLppt1lx1oVl95z8BqiKNmwnoLa6y6+mCz5jX3NOu37+t/7XWXHhgoYb37z3VvbzB12rvLtYHtaprbX/yOZurUm5vJc+9oNm16f798dWdkL/wXB5vz3tLOfL3BtV8yOgoYADVRwGRkhm/mPOvasc4M2cDs2KjZrzb9H7BfO3u2a6CAXbH4F9Y4moyaMeyWsN4plxu37C2rIq68caZMdVeSHC5ho0pa955avX0jCti2V76v2TC1r1l7+YGBWbD+TZTba8F6qxv2yteGqX3NlrV39d/bhsm9pch1ZkbXXXag2bzx7mbrqt3NtnNub6bO3FWW2++tennO7c3miT3NxMX7m7WXH5iZHWxXjbzwDWUFxfPe0t5HzOyXjIkCBkBNFDA5ogyUsN6fh1ZRHHXNWPc6p3WXzRStpTCrdTRjOGsW7PLRs2C9BSu2v/gdc5euUeWr+3XnKmCnvbuZOuvWZtOm9zcTO/bPngXrFLDuaYUTO/Y3W9btabadc3v/62xef3d5js5Kmr17nPVWzZw8945m2zm3N5MX7m42T+wppe3SA4PXxl05c93X+dfc25x7rfIlh48CBkBNFDCRpzDDBWx4Fqy/2uT2fWVRjrNuLSWsd6phd2ZreIZruIAN7xsuYO1M1NZVu5tNmzslrJ0J652C2Dv1b/WVpTBumNxblpM/c1f/a40qYOsuO9Bs3LK3lLB1e5ota+9qNk/saTZu3dtMXLJ/YEGWbrm/8A0Hm/PefG9z7nWlgClfcrgoYADURAETeYozvPDIrFmwS8os2Prt+8qNi8+6dXDVwOH7Zw1f+9UtZ91TF4eXoT/15mbqtHc3286+rZm8cHeZCbu4FKPVV97TX3jjVa+bea0TF7ezX69830AB27hl78xphJ2FWyYuLguLbNxS0jtVsb+YS+d6r1VXl5m3c6+9tznnraWAnf+me4/7v5cs/ihgANREARM5DjncKZsD14a1C3NMnXpzmcVacd3Ie2gNFLDe1xo6BXH7STvLjbNPeWf/BtnbV95YbgJ95q5m8oLp/ixV/x5lvZtwr7+7mTz3jmbqFe/t31C793V6pxL2V0K8auaUxVnXvnVvTN0u9LLq6lK8erNeipfMJwoYADVRwESOU0be/+zyzjVRr505RXHD1L5my7o9zdSZu8pS7r/8r8vzdGfChpen76WdCdt+4m+UGzP3Ctgp7yx/Pvn6/ozYtl+7rZm8YLrZsq6UsI1b9jZb1u3p32x76sxdpQieenOZBWu/xtpXH+jfNHkgnUVchm950J/5au9Ddu61pXwd738XqS8KGAA1UcBEjlNGzXqNul/a6ivba6ra2aitq+8s14ad8s7Zpxx2s+K6mRmwF76tzH71CtjJ15e0N2refvL15flOe3cpYeffUYrX6jvL4hln31bya7c1U694b7Ptle8rp0e272X1a0v56q6WOKuAXTlTLLvLzPcW/Dje/x5SbxQwAGqigIkcx/RONRy1XP/AKXpXzcwirX31gWb99nZG7NSbyyIdvXuGdRfm6K6Q2LsB84vfUdK7F9dJO2fSK2Evf08zddatZYbrFe8tqyW2pxxOnntHs3XV7mbzxrub9RftP+7jJzK1QgEDoC4KmMhxTm+J/v5S/Z2ZsO5pet2ZpN6NnPvXZZ1+Szk18Vf+bSlj3cU32gLWT7saYn9RjpN2zvy3MxM2derNM7NlL7mpmTr9llK8tu/r31LgeI+dyNQKBQyAuihgIosk/RJ26dCs2PA1YkOLWfRXHNyxv9m4de/MKoWveG9ZZOOknYOlbKiEDadfxHozYytvbKbOurXZsvaugaXjV1+59G6WLXVGAQOgJgqYyCJLbzn64VMThwtZdyn3Xglbd1lZxn7j1r3N5omyeMa2s28ri3e89F0lL7mpLMDRK1m90xJ7aRfl2P6Sm/oLc2xZe1ezYXLvrEVCjvdYiUytUMAAqIsCJrIIM3xaYq+QjSplvSLWu6dYb/n4iYv3N+svKmVs06b3N1vW3FUW1bhwdzlt8cxdzdTpt5T/9v58+i3luq+zbp253mv93c2GqX3NxI79gzNwr1HAZHFEAQOgJgqYyCJO9wbN3ZmxOU9VfPXgYyZ27G8mdpQytv6i/c2GqX1lhmz93c3miT3lv+vvbrasvWsm6/aUGydP7WsmLtk/8lRI14DJYokCBrC8vTFJ0+atYx6zI8mnkjyS5LEkn09yzWGe95okf9w+/pH2+B3H/GoVMJEqMrFj/0AJ65Wq/vbLhorX0IIeA8Wsd/wlQ7l4pqRNXLx/1oIgAzdTNgMmiygKGMDydXKSHyZ5NOML2M5230NJ7k9yX5IH220HxzzvwXb/g+3j70/ycLtt5zG+ZgVMpJJ0S9dwZs2SXTpYwHpL2/dKVG/WbGA2rXNMd6GP7s2Tu3+2CIcslihgAMvT05L8QZJvJrknowvYyiRPpJSnlZ3tK5J8oz1m9dAxa9rt32gf132uh9vnW5mjp4CJVJxRpwXOWjGxLUyzlrN/7eyCNTJXDt4Yupfj/d5FelHAAJan65P8NMn6JNMZXcDubLfvHnH8te2+Dw1t/912+1tGHDPX8x0pBUxkCWZWsbrynmbVVQf7edXrD5ZiNUfp6pet9mbQ3Rzv9yfSjQIGsPyckeRHKacHJuML2GczepYrSU7MzGmGXd9qt5844pjV7b7PHM2LbilgIiJSdRQwgOXlhCRfTPL1JM9ut01ndAH7frv9+WOe67F2/3Pavz+3/fujYx7/gnb/947gdf7JmDyugImISM1RwACWlzuT/FMGZ7WmM7qA/aTdfsKY5/p2Bme7Tmr//q0xj/+5dv+Pj+B1KmAiIrIko4ABLB+rkjyZ5MDQ9uksvgI2jlMQRUSk6ihgAMvDCSmnHX41yTOH9k1n8Z2COI4CJiIiVUcBA1gefjEzN1w+XD7QHmMRDhERkQWOAgawPDw7yQNj8qeZKUYPJHl9e4xl6EVERBY4ChgA0xl9CuIpcSNmERGRBY0CBsB0RhewJHl7u++hJPen3DvswXbbwTHPd29mTk+8rz3uoXbbzmN8rQqYiIhUHQUMgOmML2BJcmmST6csrvF4ki8kueYwz/nm9nGPt8d9OsmOY3+pCpiIiNQdBQyAmihgIiJSdRQwAGqigImISNVRwACoiQImIiJVRwEDoCYKmIiIVB0FDICaKGAiIlJ1FDAAaqKAiYhI1VHAAKiJAiYiIlVHAQOgJgqYiIhUHQUMgJooYCIiUnUUMABqooCJiEjVUcAAqIkCJiIiVUcBA6AmCpiIiFQdBQyAmihgIiJSdRQwAGqigImISNVRwACoiQImIiJVRwEDoCYKmIiIVB0FDICaKGAiIlJ1FDAAaqKAiYhI1VHAAKiJAiYiIlVHAQOgJgqYiIhUHQUMgJooYCIiUnUUMABqooCJiEjVUcAAqIkCJiIiVUcBA6AmCpiIiFQdBQyAmihgIiJSdRQwAGqigImISNVRwACoiQImIiJVRwEDoCYKmIiIVB0FDICaKGAiIlJ1FDAAaqKAiYhI1VHAAKiJAiYiIlVHAQOgJgqYiIhUHQUMgJooYCIiUnUUMABqooCJiEjVUcAAqIkCJiIiVUcBA6AmCpiIiFQdBQyAmihgIiJSdRQwAGqigImISNVRwACoiQImIiJVRwEDoCYKmIiIVB0FDICaKGAiIlJ1FDAAaqKAiYhI1VHAAKiJAiYiIlVHAQOgJgqYiIhUHQUMgJooYCIiUnUUMABqooCJiEjVUcAAqIkCJiIiVUcBA6AmCpiIiFQdBQyAmihgIiJSdRQwAGqigImISNVRwACoiQImIiJVRwEDoCYKmIiIVB0FDICaKGAiIlJ1FDAAaqKAiYhI1VHAAKiJAiYiIlVHAQOgJgqYiIhUHQUMgJooYCIiUnUUMABqooCJiEjVUcAAqIkCJiIiVUcBA6AmCpiIiFQdBQyAmihgIiJSdRQwAGqigImISNVRwACoiQImIiJVRwEDoCYKmIiIVB0FDICaKGAiIlJ1FDAAaqKAiYhI1VHAAKiJAiYiIlVHAQOgJgqYiIhUHQUMgJooYCIiUnUUMABqooCJiEjVUcAAqIkCJiIiVUcBA1g+DiVpxuS7Y45Zk+QTSX6Q5EdJ/jzJDUmeMcfX2ZHkU0keSfJYks8nueZYX3xLARMRkaqjgAEsH4eS/DDJ9Ii8a8Tjfz3Jkykl6reT3JPkaymF7SNjvsbOdv9DSe5Pcl+SB9ttB4/5HShgIiJSeRQwgOXjUJsj8bwkf5fkx0nO72x/VpI/SilUVw0dszLJE0kebv/csyLJN9pjVs/rFc+mgImISNVRwACWj0M58gJ2bUph+tCIfZvbfZ8e2n5nu333PJ9vPhQwERGpOgoYwPJxKMnfJnljkl1Jrk+yKaOv5/pwSmG6esS+E5I8nuQfkzyzs/2zGT/LdWK778Gje+l9CpiIiFQdBQxg+TiU0Qtw/HWSDUOP/UK777wxz/WVdv8ZnW3fb7c9f8wxj7X7n3MEr/VPxuRxBUxERGqOAgawfNyRcvrgi1JK0FlJfivJT5P8Q5KzO4/9y5Sy9LIxz/W5zJ7t+km77YQxx3y73X/iEbxWBUxERJZkFDAADqYUo491th3vAjaOUxBFRKTqKGAAvCylGD3c2Xa8T0EcRwETEZGqo4AB8AspxeiJzjaLcIiIiPwMooABMJVSjr7a2WYZehERkZ9BFDCA5eGMJM8dsX1lkr9KKUe7Otufl3JK4XxuxHxK3IhZRERkzihgAMvDdJJHk3w8yQeT7E/y0SQ/SilGH0/y80PHvDrJkynXbj2Q5ECSr7WP/0iSp434Om9v9z+U5P4k96WcdtikLPZxrBQwERGpOgoYwPKwIcnvpRSoH6Zcv/X9JJ9M8qaMLlNJsjbJJ5L8fUpZ+3KSGzP65s09l6acnvhoyrViX0hyzTG/g0IBExGRqqOAAVATBUxERKqOAgZATR5+ep7RPO8ZzxcREakyT88zhm/9AgCL1t+kXJf2eMpvD2Vh8rgxNaYVxJga08WeIx3Ph1O+nwFAFXrfwFg4xnThGdOFZ0wXnjFdWMYTgCXJN7iFZ0wXnjFdeMZ04RnThWU8AViSfINbeMZ04RnThWdMF54xXVjGE4AlyTe4hWdMF54xXXjGdOEZ04VlPAFYknyDW3jGdOEZ04VnTBeeMV1YxhOAJck3uIVnTBeeMV14xnThGdOFZTwBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlrkXJ/mdJN9J8uMkh5J8IMmK4/iaFovXJvnNJJ9J8v+SNEk+fJhj1iT5RJIfJPlRkj9PckOSZ8xxzI4kn0rySJLHknw+yTXH8LoXq+cneWuSjyX5Rsr4PJLks0muS/L0MccZ07ntT/I/kjyYMj4/SPKlJHekjPkoxnR+3pjyv/8m5TM8ytGMzzVJ/rh9/CPt8TuO+dUuTocyM4bD+e6YY3xOAVhyXprkeynfAH8/yb4kf9j+/WsZ/8PbcvFnKWPxaJK/yOEL2K8neTLlm/5vJ7knZRybJB8Zc8zOdv9DSe5Pcl/KD9JNkoPH/A4Wl3+T8r6+k+S/JNmbUv5/2G7/aJKnDR1jTA/vJ0n+Z8pY7kv5pcEXUt7vt5OcPPR4Yzo/J6d8Rh/N+AJ2NONzsN3/YPv4+5M83G7buXAvf9E4lDKO0yPyrhGP9zkFYEn67ynfmN4+tP3ftdt/6yl/RYvLpiSnppSCjZm7gD0vyd+lzCKe39n+rCR/1B571dAxK5M8kfJD18rO9hUpM0RNktVH//IXnc1JLs3sma5fSfJ/U97vFZ3txvTIPGvM9rtT3u8HO9uM6fw8LckfJPlmSgEYVcBWZv7js6bd/o0Mnm2wsn2eJ4aeayk41OZI+JwCsCS9NOUb0t9k9g/E/yzlt46PJ3nuU/y6FquNmbuAXdvu/9CIfZvbfZ8e2n5nu333PJ9vKdqV8n5/s7PNmB6bs1Pe7yc724zp/Fyf5KdJ1qfM1IwqYEczPr/bbn/LiGPmer6aHcqRFzCfUwCWpLemfEP6D2P292bHtjxlr2hx25i5C9iH2/1Xj9h3QkqZ/cckz+xs/2zG/1b2xMycnrQc3Jzyfu/rbDOmx+a2lPd7b2ebMT1yZ6Rcd9T7TE5ndAE7mvH5Vrv9xBHHrG73feZoXvQidijJ36ZcT7crpdxuyujruXxOAViSeqfT3DRm/79v97/tKXtFi9vGzF3AetfcnDdm/1fa/Wd0tn2/3TbuWrvH2v3Pmedrrc0JSb6c8l6nOtuN6fy8K6Uk3Jfyw3uT5H8l+eXOY4zpkTkhyReTfD3Js9tt0xldwOY7Ps/NzLWlo7yg3f+9o3jdi9mhjF6A46+TbBh6rM8pAEvSf8zcK3r1rh9571P2iha3jZm7gP1lu/9lY/Z/LrN/O/uTdtsJY475dsb/lnwp6S1G8PGh7cZ0fr6bwR9s/2uSFw09xpgemTuT/FMGx2E6o/8/c77jc1L792+NefzPtft/PN8XvcjdkXL64ItSStBZKdcZ/zTJP6ScMtvjcwrAkqSAzc/GKGA/C+9IeY9/keSXhvYZ06PzoiSXp8zefCfJuZ19xvTwVqWsvndgaPt0FLCfhd4vYD7W2eZzCsCS5BTE+dkYpyAutN6S0f87ZSXEYcb02PzzlB/iv9LZZkzndkJKcf1qBq8vSpyC+LPyspT3+3Bnm88pAEuSRTjmZ2PmLmAuGp+fG1Le35eTvHDMY4zpsftSynt+Qft3Yzq3X8zo65RG5QPtMRbhODa/kPJ+n+hs8zkFYEmyDP38bMzcBcyyyUfuPSnv7UuZKQajGNNj17vReu9eU8Z0bs9O8sCY/GlmitEDSV7fHmMZ+mMzlfJ+v9rZ5nMKwJLlRsxHbmPmLmDPSzkFZj43Dj0ly+/Goe9LeV9fzOxrvoYZ08M7LWUGYdjTM3Md5+c6243p0ZvO6FMQj2Z8ltuNmM/I6F/mrUzyVyljsauz3ecUgCXrpZn5DfnvJ9mb5A/bv38948+lXy5eneQ/t/lvKePyzc62gyMe/2TK7OEDKRfxf6097iNJnjbia7y93f9QkvtTlhB/sN02/Py1uyblfT2Z8j6nR+TNQ8cY07ndkHKvqk+mLKyzN8nvpHxOm5T7Lr1i6BhjenSmM7qAJUc3Pvdm5rS4+9rjHmq37VzA170YTKdc8/bxJB9Msj/JR1M+u027/eeHjvE5BWDJOjnJf0r5Qe0nSf5PyrUNK+Y6aJmYztzXgBwacczaJJ9I8vcpP1x8OcmNGX2z0Z5LU06neTTltM8vpJSVpWY6h7+u5lMjjjOm452VsmDOn6X80PlkkkdS3u90xs8yGtP5m874ApYc3fi8uX3c4+1xn06y49hf6qKzIcnvpRSoH6Zcv/X9lF8cvCmjy1TicwoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACLxf8HjpLNvpWuGG8AAAAASUVORK5CYII=\" width=\"432\">"
  28411. ],
  28412. "text/plain": [
  28413. "<IPython.core.display.HTML object>"
  28414. ]
  28415. },
  28416. "metadata": {},
  28417. "output_type": "display_data"
  28418. },
  28419. {
  28420. "name": "stdout",
  28421. "output_type": "stream",
  28422. "text": [
  28423. "0.0 1.0\n",
  28424. "889.0\n",
  28425. "(348, 313)\n",
  28426. "\n"
  28427. ]
  28428. },
  28429. {
  28430. "data": {
  28431. "application/javascript": [
  28432. "/* Put everything inside the global mpl namespace */\n",
  28433. "window.mpl = {};\n",
  28434. "\n",
  28435. "\n",
  28436. "mpl.get_websocket_type = function() {\n",
  28437. " if (typeof(WebSocket) !== 'undefined') {\n",
  28438. " return WebSocket;\n",
  28439. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  28440. " return MozWebSocket;\n",
  28441. " } else {\n",
  28442. " alert('Your browser does not have WebSocket support.' +\n",
  28443. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  28444. " 'Firefox 4 and 5 are also supported but you ' +\n",
  28445. " 'have to enable WebSockets in about:config.');\n",
  28446. " };\n",
  28447. "}\n",
  28448. "\n",
  28449. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  28450. " this.id = figure_id;\n",
  28451. "\n",
  28452. " this.ws = websocket;\n",
  28453. "\n",
  28454. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  28455. "\n",
  28456. " if (!this.supports_binary) {\n",
  28457. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  28458. " if (warnings) {\n",
  28459. " warnings.style.display = 'block';\n",
  28460. " warnings.textContent = (\n",
  28461. " \"This browser does not support binary websocket messages. \" +\n",
  28462. " \"Performance may be slow.\");\n",
  28463. " }\n",
  28464. " }\n",
  28465. "\n",
  28466. " this.imageObj = new Image();\n",
  28467. "\n",
  28468. " this.context = undefined;\n",
  28469. " this.message = undefined;\n",
  28470. " this.canvas = undefined;\n",
  28471. " this.rubberband_canvas = undefined;\n",
  28472. " this.rubberband_context = undefined;\n",
  28473. " this.format_dropdown = undefined;\n",
  28474. "\n",
  28475. " this.image_mode = 'full';\n",
  28476. "\n",
  28477. " this.root = $('<div/>');\n",
  28478. " this._root_extra_style(this.root)\n",
  28479. " this.root.attr('style', 'display: inline-block');\n",
  28480. "\n",
  28481. " $(parent_element).append(this.root);\n",
  28482. "\n",
  28483. " this._init_header(this);\n",
  28484. " this._init_canvas(this);\n",
  28485. " this._init_toolbar(this);\n",
  28486. "\n",
  28487. " var fig = this;\n",
  28488. "\n",
  28489. " this.waiting = false;\n",
  28490. "\n",
  28491. " this.ws.onopen = function () {\n",
  28492. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  28493. " fig.send_message(\"send_image_mode\", {});\n",
  28494. " if (mpl.ratio != 1) {\n",
  28495. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  28496. " }\n",
  28497. " fig.send_message(\"refresh\", {});\n",
  28498. " }\n",
  28499. "\n",
  28500. " this.imageObj.onload = function() {\n",
  28501. " if (fig.image_mode == 'full') {\n",
  28502. " // Full images could contain transparency (where diff images\n",
  28503. " // almost always do), so we need to clear the canvas so that\n",
  28504. " // there is no ghosting.\n",
  28505. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  28506. " }\n",
  28507. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  28508. " };\n",
  28509. "\n",
  28510. " this.imageObj.onunload = function() {\n",
  28511. " fig.ws.close();\n",
  28512. " }\n",
  28513. "\n",
  28514. " this.ws.onmessage = this._make_on_message_function(this);\n",
  28515. "\n",
  28516. " this.ondownload = ondownload;\n",
  28517. "}\n",
  28518. "\n",
  28519. "mpl.figure.prototype._init_header = function() {\n",
  28520. " var titlebar = $(\n",
  28521. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  28522. " 'ui-helper-clearfix\"/>');\n",
  28523. " var titletext = $(\n",
  28524. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  28525. " 'text-align: center; padding: 3px;\"/>');\n",
  28526. " titlebar.append(titletext)\n",
  28527. " this.root.append(titlebar);\n",
  28528. " this.header = titletext[0];\n",
  28529. "}\n",
  28530. "\n",
  28531. "\n",
  28532. "\n",
  28533. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  28534. "\n",
  28535. "}\n",
  28536. "\n",
  28537. "\n",
  28538. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  28539. "\n",
  28540. "}\n",
  28541. "\n",
  28542. "mpl.figure.prototype._init_canvas = function() {\n",
  28543. " var fig = this;\n",
  28544. "\n",
  28545. " var canvas_div = $('<div/>');\n",
  28546. "\n",
  28547. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  28548. "\n",
  28549. " function canvas_keyboard_event(event) {\n",
  28550. " return fig.key_event(event, event['data']);\n",
  28551. " }\n",
  28552. "\n",
  28553. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  28554. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  28555. " this.canvas_div = canvas_div\n",
  28556. " this._canvas_extra_style(canvas_div)\n",
  28557. " this.root.append(canvas_div);\n",
  28558. "\n",
  28559. " var canvas = $('<canvas/>');\n",
  28560. " canvas.addClass('mpl-canvas');\n",
  28561. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  28562. "\n",
  28563. " this.canvas = canvas[0];\n",
  28564. " this.context = canvas[0].getContext(\"2d\");\n",
  28565. "\n",
  28566. " var backingStore = this.context.backingStorePixelRatio ||\n",
  28567. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  28568. "\tthis.context.mozBackingStorePixelRatio ||\n",
  28569. "\tthis.context.msBackingStorePixelRatio ||\n",
  28570. "\tthis.context.oBackingStorePixelRatio ||\n",
  28571. "\tthis.context.backingStorePixelRatio || 1;\n",
  28572. "\n",
  28573. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  28574. "\n",
  28575. " var rubberband = $('<canvas/>');\n",
  28576. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  28577. "\n",
  28578. " var pass_mouse_events = true;\n",
  28579. "\n",
  28580. " canvas_div.resizable({\n",
  28581. " start: function(event, ui) {\n",
  28582. " pass_mouse_events = false;\n",
  28583. " },\n",
  28584. " resize: function(event, ui) {\n",
  28585. " fig.request_resize(ui.size.width, ui.size.height);\n",
  28586. " },\n",
  28587. " stop: function(event, ui) {\n",
  28588. " pass_mouse_events = true;\n",
  28589. " fig.request_resize(ui.size.width, ui.size.height);\n",
  28590. " },\n",
  28591. " });\n",
  28592. "\n",
  28593. " function mouse_event_fn(event) {\n",
  28594. " if (pass_mouse_events)\n",
  28595. " return fig.mouse_event(event, event['data']);\n",
  28596. " }\n",
  28597. "\n",
  28598. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  28599. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  28600. " // Throttle sequential mouse events to 1 every 20ms.\n",
  28601. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  28602. "\n",
  28603. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  28604. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  28605. "\n",
  28606. " canvas_div.on(\"wheel\", function (event) {\n",
  28607. " event = event.originalEvent;\n",
  28608. " event['data'] = 'scroll'\n",
  28609. " if (event.deltaY < 0) {\n",
  28610. " event.step = 1;\n",
  28611. " } else {\n",
  28612. " event.step = -1;\n",
  28613. " }\n",
  28614. " mouse_event_fn(event);\n",
  28615. " });\n",
  28616. "\n",
  28617. " canvas_div.append(canvas);\n",
  28618. " canvas_div.append(rubberband);\n",
  28619. "\n",
  28620. " this.rubberband = rubberband;\n",
  28621. " this.rubberband_canvas = rubberband[0];\n",
  28622. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  28623. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  28624. "\n",
  28625. " this._resize_canvas = function(width, height) {\n",
  28626. " // Keep the size of the canvas, canvas container, and rubber band\n",
  28627. " // canvas in synch.\n",
  28628. " canvas_div.css('width', width)\n",
  28629. " canvas_div.css('height', height)\n",
  28630. "\n",
  28631. " canvas.attr('width', width * mpl.ratio);\n",
  28632. " canvas.attr('height', height * mpl.ratio);\n",
  28633. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  28634. "\n",
  28635. " rubberband.attr('width', width);\n",
  28636. " rubberband.attr('height', height);\n",
  28637. " }\n",
  28638. "\n",
  28639. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  28640. " // upon first draw.\n",
  28641. " this._resize_canvas(600, 600);\n",
  28642. "\n",
  28643. " // Disable right mouse context menu.\n",
  28644. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  28645. " return false;\n",
  28646. " });\n",
  28647. "\n",
  28648. " function set_focus () {\n",
  28649. " canvas.focus();\n",
  28650. " canvas_div.focus();\n",
  28651. " }\n",
  28652. "\n",
  28653. " window.setTimeout(set_focus, 100);\n",
  28654. "}\n",
  28655. "\n",
  28656. "mpl.figure.prototype._init_toolbar = function() {\n",
  28657. " var fig = this;\n",
  28658. "\n",
  28659. " var nav_element = $('<div/>')\n",
  28660. " nav_element.attr('style', 'width: 100%');\n",
  28661. " this.root.append(nav_element);\n",
  28662. "\n",
  28663. " // Define a callback function for later on.\n",
  28664. " function toolbar_event(event) {\n",
  28665. " return fig.toolbar_button_onclick(event['data']);\n",
  28666. " }\n",
  28667. " function toolbar_mouse_event(event) {\n",
  28668. " return fig.toolbar_button_onmouseover(event['data']);\n",
  28669. " }\n",
  28670. "\n",
  28671. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  28672. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  28673. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  28674. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  28675. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  28676. "\n",
  28677. " if (!name) {\n",
  28678. " // put a spacer in here.\n",
  28679. " continue;\n",
  28680. " }\n",
  28681. " var button = $('<button/>');\n",
  28682. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  28683. " 'ui-button-icon-only');\n",
  28684. " button.attr('role', 'button');\n",
  28685. " button.attr('aria-disabled', 'false');\n",
  28686. " button.click(method_name, toolbar_event);\n",
  28687. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  28688. "\n",
  28689. " var icon_img = $('<span/>');\n",
  28690. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  28691. " icon_img.addClass(image);\n",
  28692. " icon_img.addClass('ui-corner-all');\n",
  28693. "\n",
  28694. " var tooltip_span = $('<span/>');\n",
  28695. " tooltip_span.addClass('ui-button-text');\n",
  28696. " tooltip_span.html(tooltip);\n",
  28697. "\n",
  28698. " button.append(icon_img);\n",
  28699. " button.append(tooltip_span);\n",
  28700. "\n",
  28701. " nav_element.append(button);\n",
  28702. " }\n",
  28703. "\n",
  28704. " var fmt_picker_span = $('<span/>');\n",
  28705. "\n",
  28706. " var fmt_picker = $('<select/>');\n",
  28707. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  28708. " fmt_picker_span.append(fmt_picker);\n",
  28709. " nav_element.append(fmt_picker_span);\n",
  28710. " this.format_dropdown = fmt_picker[0];\n",
  28711. "\n",
  28712. " for (var ind in mpl.extensions) {\n",
  28713. " var fmt = mpl.extensions[ind];\n",
  28714. " var option = $(\n",
  28715. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  28716. " fmt_picker.append(option)\n",
  28717. " }\n",
  28718. "\n",
  28719. " // Add hover states to the ui-buttons\n",
  28720. " $( \".ui-button\" ).hover(\n",
  28721. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  28722. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  28723. " );\n",
  28724. "\n",
  28725. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  28726. " nav_element.append(status_bar);\n",
  28727. " this.message = status_bar[0];\n",
  28728. "}\n",
  28729. "\n",
  28730. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  28731. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  28732. " // which will in turn request a refresh of the image.\n",
  28733. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  28734. "}\n",
  28735. "\n",
  28736. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  28737. " properties['type'] = type;\n",
  28738. " properties['figure_id'] = this.id;\n",
  28739. " this.ws.send(JSON.stringify(properties));\n",
  28740. "}\n",
  28741. "\n",
  28742. "mpl.figure.prototype.send_draw_message = function() {\n",
  28743. " if (!this.waiting) {\n",
  28744. " this.waiting = true;\n",
  28745. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  28746. " }\n",
  28747. "}\n",
  28748. "\n",
  28749. "\n",
  28750. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  28751. " var format_dropdown = fig.format_dropdown;\n",
  28752. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  28753. " fig.ondownload(fig, format);\n",
  28754. "}\n",
  28755. "\n",
  28756. "\n",
  28757. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  28758. " var size = msg['size'];\n",
  28759. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  28760. " fig._resize_canvas(size[0], size[1]);\n",
  28761. " fig.send_message(\"refresh\", {});\n",
  28762. " };\n",
  28763. "}\n",
  28764. "\n",
  28765. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  28766. " var x0 = msg['x0'] / mpl.ratio;\n",
  28767. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  28768. " var x1 = msg['x1'] / mpl.ratio;\n",
  28769. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  28770. " x0 = Math.floor(x0) + 0.5;\n",
  28771. " y0 = Math.floor(y0) + 0.5;\n",
  28772. " x1 = Math.floor(x1) + 0.5;\n",
  28773. " y1 = Math.floor(y1) + 0.5;\n",
  28774. " var min_x = Math.min(x0, x1);\n",
  28775. " var min_y = Math.min(y0, y1);\n",
  28776. " var width = Math.abs(x1 - x0);\n",
  28777. " var height = Math.abs(y1 - y0);\n",
  28778. "\n",
  28779. " fig.rubberband_context.clearRect(\n",
  28780. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  28781. "\n",
  28782. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  28783. "}\n",
  28784. "\n",
  28785. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  28786. " // Updates the figure title.\n",
  28787. " fig.header.textContent = msg['label'];\n",
  28788. "}\n",
  28789. "\n",
  28790. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  28791. " var cursor = msg['cursor'];\n",
  28792. " switch(cursor)\n",
  28793. " {\n",
  28794. " case 0:\n",
  28795. " cursor = 'pointer';\n",
  28796. " break;\n",
  28797. " case 1:\n",
  28798. " cursor = 'default';\n",
  28799. " break;\n",
  28800. " case 2:\n",
  28801. " cursor = 'crosshair';\n",
  28802. " break;\n",
  28803. " case 3:\n",
  28804. " cursor = 'move';\n",
  28805. " break;\n",
  28806. " }\n",
  28807. " fig.rubberband_canvas.style.cursor = cursor;\n",
  28808. "}\n",
  28809. "\n",
  28810. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  28811. " fig.message.textContent = msg['message'];\n",
  28812. "}\n",
  28813. "\n",
  28814. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  28815. " // Request the server to send over a new figure.\n",
  28816. " fig.send_draw_message();\n",
  28817. "}\n",
  28818. "\n",
  28819. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  28820. " fig.image_mode = msg['mode'];\n",
  28821. "}\n",
  28822. "\n",
  28823. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  28824. " // Called whenever the canvas gets updated.\n",
  28825. " this.send_message(\"ack\", {});\n",
  28826. "}\n",
  28827. "\n",
  28828. "// A function to construct a web socket function for onmessage handling.\n",
  28829. "// Called in the figure constructor.\n",
  28830. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  28831. " return function socket_on_message(evt) {\n",
  28832. " if (evt.data instanceof Blob) {\n",
  28833. " /* FIXME: We get \"Resource interpreted as Image but\n",
  28834. " * transferred with MIME type text/plain:\" errors on\n",
  28835. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  28836. " * to be part of the websocket stream */\n",
  28837. " evt.data.type = \"image/png\";\n",
  28838. "\n",
  28839. " /* Free the memory for the previous frames */\n",
  28840. " if (fig.imageObj.src) {\n",
  28841. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  28842. " fig.imageObj.src);\n",
  28843. " }\n",
  28844. "\n",
  28845. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  28846. " evt.data);\n",
  28847. " fig.updated_canvas_event();\n",
  28848. " fig.waiting = false;\n",
  28849. " return;\n",
  28850. " }\n",
  28851. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  28852. " fig.imageObj.src = evt.data;\n",
  28853. " fig.updated_canvas_event();\n",
  28854. " fig.waiting = false;\n",
  28855. " return;\n",
  28856. " }\n",
  28857. "\n",
  28858. " var msg = JSON.parse(evt.data);\n",
  28859. " var msg_type = msg['type'];\n",
  28860. "\n",
  28861. " // Call the \"handle_{type}\" callback, which takes\n",
  28862. " // the figure and JSON message as its only arguments.\n",
  28863. " try {\n",
  28864. " var callback = fig[\"handle_\" + msg_type];\n",
  28865. " } catch (e) {\n",
  28866. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  28867. " return;\n",
  28868. " }\n",
  28869. "\n",
  28870. " if (callback) {\n",
  28871. " try {\n",
  28872. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  28873. " callback(fig, msg);\n",
  28874. " } catch (e) {\n",
  28875. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  28876. " }\n",
  28877. " }\n",
  28878. " };\n",
  28879. "}\n",
  28880. "\n",
  28881. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  28882. "mpl.findpos = function(e) {\n",
  28883. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  28884. " var targ;\n",
  28885. " if (!e)\n",
  28886. " e = window.event;\n",
  28887. " if (e.target)\n",
  28888. " targ = e.target;\n",
  28889. " else if (e.srcElement)\n",
  28890. " targ = e.srcElement;\n",
  28891. " if (targ.nodeType == 3) // defeat Safari bug\n",
  28892. " targ = targ.parentNode;\n",
  28893. "\n",
  28894. " // jQuery normalizes the pageX and pageY\n",
  28895. " // pageX,Y are the mouse positions relative to the document\n",
  28896. " // offset() returns the position of the element relative to the document\n",
  28897. " var x = e.pageX - $(targ).offset().left;\n",
  28898. " var y = e.pageY - $(targ).offset().top;\n",
  28899. "\n",
  28900. " return {\"x\": x, \"y\": y};\n",
  28901. "};\n",
  28902. "\n",
  28903. "/*\n",
  28904. " * return a copy of an object with only non-object keys\n",
  28905. " * we need this to avoid circular references\n",
  28906. " * http://stackoverflow.com/a/24161582/3208463\n",
  28907. " */\n",
  28908. "function simpleKeys (original) {\n",
  28909. " return Object.keys(original).reduce(function (obj, key) {\n",
  28910. " if (typeof original[key] !== 'object')\n",
  28911. " obj[key] = original[key]\n",
  28912. " return obj;\n",
  28913. " }, {});\n",
  28914. "}\n",
  28915. "\n",
  28916. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  28917. " var canvas_pos = mpl.findpos(event)\n",
  28918. "\n",
  28919. " if (name === 'button_press')\n",
  28920. " {\n",
  28921. " this.canvas.focus();\n",
  28922. " this.canvas_div.focus();\n",
  28923. " }\n",
  28924. "\n",
  28925. " var x = canvas_pos.x * mpl.ratio;\n",
  28926. " var y = canvas_pos.y * mpl.ratio;\n",
  28927. "\n",
  28928. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  28929. " step: event.step,\n",
  28930. " guiEvent: simpleKeys(event)});\n",
  28931. "\n",
  28932. " /* This prevents the web browser from automatically changing to\n",
  28933. " * the text insertion cursor when the button is pressed. We want\n",
  28934. " * to control all of the cursor setting manually through the\n",
  28935. " * 'cursor' event from matplotlib */\n",
  28936. " event.preventDefault();\n",
  28937. " return false;\n",
  28938. "}\n",
  28939. "\n",
  28940. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  28941. " // Handle any extra behaviour associated with a key event\n",
  28942. "}\n",
  28943. "\n",
  28944. "mpl.figure.prototype.key_event = function(event, name) {\n",
  28945. "\n",
  28946. " // Prevent repeat events\n",
  28947. " if (name == 'key_press')\n",
  28948. " {\n",
  28949. " if (event.which === this._key)\n",
  28950. " return;\n",
  28951. " else\n",
  28952. " this._key = event.which;\n",
  28953. " }\n",
  28954. " if (name == 'key_release')\n",
  28955. " this._key = null;\n",
  28956. "\n",
  28957. " var value = '';\n",
  28958. " if (event.ctrlKey && event.which != 17)\n",
  28959. " value += \"ctrl+\";\n",
  28960. " if (event.altKey && event.which != 18)\n",
  28961. " value += \"alt+\";\n",
  28962. " if (event.shiftKey && event.which != 16)\n",
  28963. " value += \"shift+\";\n",
  28964. "\n",
  28965. " value += 'k';\n",
  28966. " value += event.which.toString();\n",
  28967. "\n",
  28968. " this._key_event_extra(event, name);\n",
  28969. "\n",
  28970. " this.send_message(name, {key: value,\n",
  28971. " guiEvent: simpleKeys(event)});\n",
  28972. " return false;\n",
  28973. "}\n",
  28974. "\n",
  28975. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  28976. " if (name == 'download') {\n",
  28977. " this.handle_save(this, null);\n",
  28978. " } else {\n",
  28979. " this.send_message(\"toolbar_button\", {name: name});\n",
  28980. " }\n",
  28981. "};\n",
  28982. "\n",
  28983. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  28984. " this.message.textContent = tooltip;\n",
  28985. "};\n",
  28986. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  28987. "\n",
  28988. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  28989. "\n",
  28990. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  28991. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  28992. " // object with the appropriate methods. Currently this is a non binary\n",
  28993. " // socket, so there is still some room for performance tuning.\n",
  28994. " var ws = {};\n",
  28995. "\n",
  28996. " ws.close = function() {\n",
  28997. " comm.close()\n",
  28998. " };\n",
  28999. " ws.send = function(m) {\n",
  29000. " //console.log('sending', m);\n",
  29001. " comm.send(m);\n",
  29002. " };\n",
  29003. " // Register the callback with on_msg.\n",
  29004. " comm.on_msg(function(msg) {\n",
  29005. " //console.log('receiving', msg['content']['data'], msg);\n",
  29006. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  29007. " ws.onmessage(msg['content']['data'])\n",
  29008. " });\n",
  29009. " return ws;\n",
  29010. "}\n",
  29011. "\n",
  29012. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  29013. " // This is the function which gets called when the mpl process\n",
  29014. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  29015. "\n",
  29016. " var id = msg.content.data.id;\n",
  29017. " // Get hold of the div created by the display call when the Comm\n",
  29018. " // socket was opened in Python.\n",
  29019. " var element = $(\"#\" + id);\n",
  29020. " var ws_proxy = comm_websocket_adapter(comm)\n",
  29021. "\n",
  29022. " function ondownload(figure, format) {\n",
  29023. " window.open(figure.imageObj.src);\n",
  29024. " }\n",
  29025. "\n",
  29026. " var fig = new mpl.figure(id, ws_proxy,\n",
  29027. " ondownload,\n",
  29028. " element.get(0));\n",
  29029. "\n",
  29030. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  29031. " // web socket which is closed, not our websocket->open comm proxy.\n",
  29032. " ws_proxy.onopen();\n",
  29033. "\n",
  29034. " fig.parent_element = element.get(0);\n",
  29035. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  29036. " if (!fig.cell_info) {\n",
  29037. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  29038. " return;\n",
  29039. " }\n",
  29040. "\n",
  29041. " var output_index = fig.cell_info[2]\n",
  29042. " var cell = fig.cell_info[0];\n",
  29043. "\n",
  29044. "};\n",
  29045. "\n",
  29046. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  29047. " var width = fig.canvas.width/mpl.ratio\n",
  29048. " fig.root.unbind('remove')\n",
  29049. "\n",
  29050. " // Update the output cell to use the data from the current canvas.\n",
  29051. " fig.push_to_output();\n",
  29052. " var dataURL = fig.canvas.toDataURL();\n",
  29053. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  29054. " // the notebook keyboard shortcuts fail.\n",
  29055. " IPython.keyboard_manager.enable()\n",
  29056. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  29057. " fig.close_ws(fig, msg);\n",
  29058. "}\n",
  29059. "\n",
  29060. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  29061. " fig.send_message('closing', msg);\n",
  29062. " // fig.ws.close()\n",
  29063. "}\n",
  29064. "\n",
  29065. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  29066. " // Turn the data on the canvas into data in the output cell.\n",
  29067. " var width = this.canvas.width/mpl.ratio\n",
  29068. " var dataURL = this.canvas.toDataURL();\n",
  29069. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  29070. "}\n",
  29071. "\n",
  29072. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  29073. " // Tell IPython that the notebook contents must change.\n",
  29074. " IPython.notebook.set_dirty(true);\n",
  29075. " this.send_message(\"ack\", {});\n",
  29076. " var fig = this;\n",
  29077. " // Wait a second, then push the new image to the DOM so\n",
  29078. " // that it is saved nicely (might be nice to debounce this).\n",
  29079. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  29080. "}\n",
  29081. "\n",
  29082. "mpl.figure.prototype._init_toolbar = function() {\n",
  29083. " var fig = this;\n",
  29084. "\n",
  29085. " var nav_element = $('<div/>')\n",
  29086. " nav_element.attr('style', 'width: 100%');\n",
  29087. " this.root.append(nav_element);\n",
  29088. "\n",
  29089. " // Define a callback function for later on.\n",
  29090. " function toolbar_event(event) {\n",
  29091. " return fig.toolbar_button_onclick(event['data']);\n",
  29092. " }\n",
  29093. " function toolbar_mouse_event(event) {\n",
  29094. " return fig.toolbar_button_onmouseover(event['data']);\n",
  29095. " }\n",
  29096. "\n",
  29097. " for(var toolbar_ind in mpl.toolbar_items){\n",
  29098. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  29099. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  29100. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  29101. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  29102. "\n",
  29103. " if (!name) { continue; };\n",
  29104. "\n",
  29105. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  29106. " button.click(method_name, toolbar_event);\n",
  29107. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  29108. " nav_element.append(button);\n",
  29109. " }\n",
  29110. "\n",
  29111. " // Add the status bar.\n",
  29112. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  29113. " nav_element.append(status_bar);\n",
  29114. " this.message = status_bar[0];\n",
  29115. "\n",
  29116. " // Add the close button to the window.\n",
  29117. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  29118. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  29119. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  29120. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  29121. " buttongrp.append(button);\n",
  29122. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  29123. " titlebar.prepend(buttongrp);\n",
  29124. "}\n",
  29125. "\n",
  29126. "mpl.figure.prototype._root_extra_style = function(el){\n",
  29127. " var fig = this\n",
  29128. " el.on(\"remove\", function(){\n",
  29129. "\tfig.close_ws(fig, {});\n",
  29130. " });\n",
  29131. "}\n",
  29132. "\n",
  29133. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  29134. " // this is important to make the div 'focusable\n",
  29135. " el.attr('tabindex', 0)\n",
  29136. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  29137. " // off when our div gets focus\n",
  29138. "\n",
  29139. " // location in version 3\n",
  29140. " if (IPython.notebook.keyboard_manager) {\n",
  29141. " IPython.notebook.keyboard_manager.register_events(el);\n",
  29142. " }\n",
  29143. " else {\n",
  29144. " // location in version 2\n",
  29145. " IPython.keyboard_manager.register_events(el);\n",
  29146. " }\n",
  29147. "\n",
  29148. "}\n",
  29149. "\n",
  29150. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  29151. " var manager = IPython.notebook.keyboard_manager;\n",
  29152. " if (!manager)\n",
  29153. " manager = IPython.keyboard_manager;\n",
  29154. "\n",
  29155. " // Check for shift+enter\n",
  29156. " if (event.shiftKey && event.which == 13) {\n",
  29157. " this.canvas_div.blur();\n",
  29158. " event.shiftKey = false;\n",
  29159. " // Send a \"J\" for go to next cell\n",
  29160. " event.which = 74;\n",
  29161. " event.keyCode = 74;\n",
  29162. " manager.command_mode();\n",
  29163. " manager.handle_keydown(event);\n",
  29164. " }\n",
  29165. "}\n",
  29166. "\n",
  29167. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  29168. " fig.ondownload(fig, null);\n",
  29169. "}\n",
  29170. "\n",
  29171. "\n",
  29172. "mpl.find_output_cell = function(html_output) {\n",
  29173. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  29174. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  29175. " // IPython event is triggered only after the cells have been serialised, which for\n",
  29176. " // our purposes (turning an active figure into a static one), is too late.\n",
  29177. " var cells = IPython.notebook.get_cells();\n",
  29178. " var ncells = cells.length;\n",
  29179. " for (var i=0; i<ncells; i++) {\n",
  29180. " var cell = cells[i];\n",
  29181. " if (cell.cell_type === 'code'){\n",
  29182. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  29183. " var data = cell.output_area.outputs[j];\n",
  29184. " if (data.data) {\n",
  29185. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  29186. " data = data.data;\n",
  29187. " }\n",
  29188. " if (data['text/html'] == html_output) {\n",
  29189. " return [cell, data, j];\n",
  29190. " }\n",
  29191. " }\n",
  29192. " }\n",
  29193. " }\n",
  29194. "}\n",
  29195. "\n",
  29196. "// Register the function which deals with the matplotlib target/channel.\n",
  29197. "// The kernel may be null if the page has been refreshed.\n",
  29198. "if (IPython.notebook.kernel != null) {\n",
  29199. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  29200. "}\n"
  29201. ],
  29202. "text/plain": [
  29203. "<IPython.core.display.Javascript object>"
  29204. ]
  29205. },
  29206. "metadata": {},
  29207. "output_type": "display_data"
  29208. },
  29209. {
  29210. "data": {
  29211. "text/html": [
  29212. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  29213. ],
  29214. "text/plain": [
  29215. "<IPython.core.display.HTML object>"
  29216. ]
  29217. },
  29218. "metadata": {},
  29219. "output_type": "display_data"
  29220. },
  29221. {
  29222. "name": "stdout",
  29223. "output_type": "stream",
  29224. "text": [
  29225. "0 1\n",
  29226. "902\n",
  29227. "(349, 312)\n",
  29228. "\n"
  29229. ]
  29230. },
  29231. {
  29232. "data": {
  29233. "application/javascript": [
  29234. "/* Put everything inside the global mpl namespace */\n",
  29235. "window.mpl = {};\n",
  29236. "\n",
  29237. "\n",
  29238. "mpl.get_websocket_type = function() {\n",
  29239. " if (typeof(WebSocket) !== 'undefined') {\n",
  29240. " return WebSocket;\n",
  29241. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  29242. " return MozWebSocket;\n",
  29243. " } else {\n",
  29244. " alert('Your browser does not have WebSocket support.' +\n",
  29245. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  29246. " 'Firefox 4 and 5 are also supported but you ' +\n",
  29247. " 'have to enable WebSockets in about:config.');\n",
  29248. " };\n",
  29249. "}\n",
  29250. "\n",
  29251. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  29252. " this.id = figure_id;\n",
  29253. "\n",
  29254. " this.ws = websocket;\n",
  29255. "\n",
  29256. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  29257. "\n",
  29258. " if (!this.supports_binary) {\n",
  29259. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  29260. " if (warnings) {\n",
  29261. " warnings.style.display = 'block';\n",
  29262. " warnings.textContent = (\n",
  29263. " \"This browser does not support binary websocket messages. \" +\n",
  29264. " \"Performance may be slow.\");\n",
  29265. " }\n",
  29266. " }\n",
  29267. "\n",
  29268. " this.imageObj = new Image();\n",
  29269. "\n",
  29270. " this.context = undefined;\n",
  29271. " this.message = undefined;\n",
  29272. " this.canvas = undefined;\n",
  29273. " this.rubberband_canvas = undefined;\n",
  29274. " this.rubberband_context = undefined;\n",
  29275. " this.format_dropdown = undefined;\n",
  29276. "\n",
  29277. " this.image_mode = 'full';\n",
  29278. "\n",
  29279. " this.root = $('<div/>');\n",
  29280. " this._root_extra_style(this.root)\n",
  29281. " this.root.attr('style', 'display: inline-block');\n",
  29282. "\n",
  29283. " $(parent_element).append(this.root);\n",
  29284. "\n",
  29285. " this._init_header(this);\n",
  29286. " this._init_canvas(this);\n",
  29287. " this._init_toolbar(this);\n",
  29288. "\n",
  29289. " var fig = this;\n",
  29290. "\n",
  29291. " this.waiting = false;\n",
  29292. "\n",
  29293. " this.ws.onopen = function () {\n",
  29294. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  29295. " fig.send_message(\"send_image_mode\", {});\n",
  29296. " if (mpl.ratio != 1) {\n",
  29297. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  29298. " }\n",
  29299. " fig.send_message(\"refresh\", {});\n",
  29300. " }\n",
  29301. "\n",
  29302. " this.imageObj.onload = function() {\n",
  29303. " if (fig.image_mode == 'full') {\n",
  29304. " // Full images could contain transparency (where diff images\n",
  29305. " // almost always do), so we need to clear the canvas so that\n",
  29306. " // there is no ghosting.\n",
  29307. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  29308. " }\n",
  29309. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  29310. " };\n",
  29311. "\n",
  29312. " this.imageObj.onunload = function() {\n",
  29313. " fig.ws.close();\n",
  29314. " }\n",
  29315. "\n",
  29316. " this.ws.onmessage = this._make_on_message_function(this);\n",
  29317. "\n",
  29318. " this.ondownload = ondownload;\n",
  29319. "}\n",
  29320. "\n",
  29321. "mpl.figure.prototype._init_header = function() {\n",
  29322. " var titlebar = $(\n",
  29323. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  29324. " 'ui-helper-clearfix\"/>');\n",
  29325. " var titletext = $(\n",
  29326. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  29327. " 'text-align: center; padding: 3px;\"/>');\n",
  29328. " titlebar.append(titletext)\n",
  29329. " this.root.append(titlebar);\n",
  29330. " this.header = titletext[0];\n",
  29331. "}\n",
  29332. "\n",
  29333. "\n",
  29334. "\n",
  29335. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  29336. "\n",
  29337. "}\n",
  29338. "\n",
  29339. "\n",
  29340. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  29341. "\n",
  29342. "}\n",
  29343. "\n",
  29344. "mpl.figure.prototype._init_canvas = function() {\n",
  29345. " var fig = this;\n",
  29346. "\n",
  29347. " var canvas_div = $('<div/>');\n",
  29348. "\n",
  29349. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  29350. "\n",
  29351. " function canvas_keyboard_event(event) {\n",
  29352. " return fig.key_event(event, event['data']);\n",
  29353. " }\n",
  29354. "\n",
  29355. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  29356. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  29357. " this.canvas_div = canvas_div\n",
  29358. " this._canvas_extra_style(canvas_div)\n",
  29359. " this.root.append(canvas_div);\n",
  29360. "\n",
  29361. " var canvas = $('<canvas/>');\n",
  29362. " canvas.addClass('mpl-canvas');\n",
  29363. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  29364. "\n",
  29365. " this.canvas = canvas[0];\n",
  29366. " this.context = canvas[0].getContext(\"2d\");\n",
  29367. "\n",
  29368. " var backingStore = this.context.backingStorePixelRatio ||\n",
  29369. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  29370. "\tthis.context.mozBackingStorePixelRatio ||\n",
  29371. "\tthis.context.msBackingStorePixelRatio ||\n",
  29372. "\tthis.context.oBackingStorePixelRatio ||\n",
  29373. "\tthis.context.backingStorePixelRatio || 1;\n",
  29374. "\n",
  29375. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  29376. "\n",
  29377. " var rubberband = $('<canvas/>');\n",
  29378. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  29379. "\n",
  29380. " var pass_mouse_events = true;\n",
  29381. "\n",
  29382. " canvas_div.resizable({\n",
  29383. " start: function(event, ui) {\n",
  29384. " pass_mouse_events = false;\n",
  29385. " },\n",
  29386. " resize: function(event, ui) {\n",
  29387. " fig.request_resize(ui.size.width, ui.size.height);\n",
  29388. " },\n",
  29389. " stop: function(event, ui) {\n",
  29390. " pass_mouse_events = true;\n",
  29391. " fig.request_resize(ui.size.width, ui.size.height);\n",
  29392. " },\n",
  29393. " });\n",
  29394. "\n",
  29395. " function mouse_event_fn(event) {\n",
  29396. " if (pass_mouse_events)\n",
  29397. " return fig.mouse_event(event, event['data']);\n",
  29398. " }\n",
  29399. "\n",
  29400. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  29401. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  29402. " // Throttle sequential mouse events to 1 every 20ms.\n",
  29403. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  29404. "\n",
  29405. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  29406. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  29407. "\n",
  29408. " canvas_div.on(\"wheel\", function (event) {\n",
  29409. " event = event.originalEvent;\n",
  29410. " event['data'] = 'scroll'\n",
  29411. " if (event.deltaY < 0) {\n",
  29412. " event.step = 1;\n",
  29413. " } else {\n",
  29414. " event.step = -1;\n",
  29415. " }\n",
  29416. " mouse_event_fn(event);\n",
  29417. " });\n",
  29418. "\n",
  29419. " canvas_div.append(canvas);\n",
  29420. " canvas_div.append(rubberband);\n",
  29421. "\n",
  29422. " this.rubberband = rubberband;\n",
  29423. " this.rubberband_canvas = rubberband[0];\n",
  29424. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  29425. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  29426. "\n",
  29427. " this._resize_canvas = function(width, height) {\n",
  29428. " // Keep the size of the canvas, canvas container, and rubber band\n",
  29429. " // canvas in synch.\n",
  29430. " canvas_div.css('width', width)\n",
  29431. " canvas_div.css('height', height)\n",
  29432. "\n",
  29433. " canvas.attr('width', width * mpl.ratio);\n",
  29434. " canvas.attr('height', height * mpl.ratio);\n",
  29435. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  29436. "\n",
  29437. " rubberband.attr('width', width);\n",
  29438. " rubberband.attr('height', height);\n",
  29439. " }\n",
  29440. "\n",
  29441. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  29442. " // upon first draw.\n",
  29443. " this._resize_canvas(600, 600);\n",
  29444. "\n",
  29445. " // Disable right mouse context menu.\n",
  29446. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  29447. " return false;\n",
  29448. " });\n",
  29449. "\n",
  29450. " function set_focus () {\n",
  29451. " canvas.focus();\n",
  29452. " canvas_div.focus();\n",
  29453. " }\n",
  29454. "\n",
  29455. " window.setTimeout(set_focus, 100);\n",
  29456. "}\n",
  29457. "\n",
  29458. "mpl.figure.prototype._init_toolbar = function() {\n",
  29459. " var fig = this;\n",
  29460. "\n",
  29461. " var nav_element = $('<div/>')\n",
  29462. " nav_element.attr('style', 'width: 100%');\n",
  29463. " this.root.append(nav_element);\n",
  29464. "\n",
  29465. " // Define a callback function for later on.\n",
  29466. " function toolbar_event(event) {\n",
  29467. " return fig.toolbar_button_onclick(event['data']);\n",
  29468. " }\n",
  29469. " function toolbar_mouse_event(event) {\n",
  29470. " return fig.toolbar_button_onmouseover(event['data']);\n",
  29471. " }\n",
  29472. "\n",
  29473. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  29474. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  29475. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  29476. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  29477. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  29478. "\n",
  29479. " if (!name) {\n",
  29480. " // put a spacer in here.\n",
  29481. " continue;\n",
  29482. " }\n",
  29483. " var button = $('<button/>');\n",
  29484. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  29485. " 'ui-button-icon-only');\n",
  29486. " button.attr('role', 'button');\n",
  29487. " button.attr('aria-disabled', 'false');\n",
  29488. " button.click(method_name, toolbar_event);\n",
  29489. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  29490. "\n",
  29491. " var icon_img = $('<span/>');\n",
  29492. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  29493. " icon_img.addClass(image);\n",
  29494. " icon_img.addClass('ui-corner-all');\n",
  29495. "\n",
  29496. " var tooltip_span = $('<span/>');\n",
  29497. " tooltip_span.addClass('ui-button-text');\n",
  29498. " tooltip_span.html(tooltip);\n",
  29499. "\n",
  29500. " button.append(icon_img);\n",
  29501. " button.append(tooltip_span);\n",
  29502. "\n",
  29503. " nav_element.append(button);\n",
  29504. " }\n",
  29505. "\n",
  29506. " var fmt_picker_span = $('<span/>');\n",
  29507. "\n",
  29508. " var fmt_picker = $('<select/>');\n",
  29509. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  29510. " fmt_picker_span.append(fmt_picker);\n",
  29511. " nav_element.append(fmt_picker_span);\n",
  29512. " this.format_dropdown = fmt_picker[0];\n",
  29513. "\n",
  29514. " for (var ind in mpl.extensions) {\n",
  29515. " var fmt = mpl.extensions[ind];\n",
  29516. " var option = $(\n",
  29517. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  29518. " fmt_picker.append(option)\n",
  29519. " }\n",
  29520. "\n",
  29521. " // Add hover states to the ui-buttons\n",
  29522. " $( \".ui-button\" ).hover(\n",
  29523. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  29524. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  29525. " );\n",
  29526. "\n",
  29527. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  29528. " nav_element.append(status_bar);\n",
  29529. " this.message = status_bar[0];\n",
  29530. "}\n",
  29531. "\n",
  29532. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  29533. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  29534. " // which will in turn request a refresh of the image.\n",
  29535. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  29536. "}\n",
  29537. "\n",
  29538. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  29539. " properties['type'] = type;\n",
  29540. " properties['figure_id'] = this.id;\n",
  29541. " this.ws.send(JSON.stringify(properties));\n",
  29542. "}\n",
  29543. "\n",
  29544. "mpl.figure.prototype.send_draw_message = function() {\n",
  29545. " if (!this.waiting) {\n",
  29546. " this.waiting = true;\n",
  29547. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  29548. " }\n",
  29549. "}\n",
  29550. "\n",
  29551. "\n",
  29552. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  29553. " var format_dropdown = fig.format_dropdown;\n",
  29554. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  29555. " fig.ondownload(fig, format);\n",
  29556. "}\n",
  29557. "\n",
  29558. "\n",
  29559. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  29560. " var size = msg['size'];\n",
  29561. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  29562. " fig._resize_canvas(size[0], size[1]);\n",
  29563. " fig.send_message(\"refresh\", {});\n",
  29564. " };\n",
  29565. "}\n",
  29566. "\n",
  29567. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  29568. " var x0 = msg['x0'] / mpl.ratio;\n",
  29569. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  29570. " var x1 = msg['x1'] / mpl.ratio;\n",
  29571. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  29572. " x0 = Math.floor(x0) + 0.5;\n",
  29573. " y0 = Math.floor(y0) + 0.5;\n",
  29574. " x1 = Math.floor(x1) + 0.5;\n",
  29575. " y1 = Math.floor(y1) + 0.5;\n",
  29576. " var min_x = Math.min(x0, x1);\n",
  29577. " var min_y = Math.min(y0, y1);\n",
  29578. " var width = Math.abs(x1 - x0);\n",
  29579. " var height = Math.abs(y1 - y0);\n",
  29580. "\n",
  29581. " fig.rubberband_context.clearRect(\n",
  29582. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  29583. "\n",
  29584. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  29585. "}\n",
  29586. "\n",
  29587. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  29588. " // Updates the figure title.\n",
  29589. " fig.header.textContent = msg['label'];\n",
  29590. "}\n",
  29591. "\n",
  29592. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  29593. " var cursor = msg['cursor'];\n",
  29594. " switch(cursor)\n",
  29595. " {\n",
  29596. " case 0:\n",
  29597. " cursor = 'pointer';\n",
  29598. " break;\n",
  29599. " case 1:\n",
  29600. " cursor = 'default';\n",
  29601. " break;\n",
  29602. " case 2:\n",
  29603. " cursor = 'crosshair';\n",
  29604. " break;\n",
  29605. " case 3:\n",
  29606. " cursor = 'move';\n",
  29607. " break;\n",
  29608. " }\n",
  29609. " fig.rubberband_canvas.style.cursor = cursor;\n",
  29610. "}\n",
  29611. "\n",
  29612. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  29613. " fig.message.textContent = msg['message'];\n",
  29614. "}\n",
  29615. "\n",
  29616. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  29617. " // Request the server to send over a new figure.\n",
  29618. " fig.send_draw_message();\n",
  29619. "}\n",
  29620. "\n",
  29621. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  29622. " fig.image_mode = msg['mode'];\n",
  29623. "}\n",
  29624. "\n",
  29625. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  29626. " // Called whenever the canvas gets updated.\n",
  29627. " this.send_message(\"ack\", {});\n",
  29628. "}\n",
  29629. "\n",
  29630. "// A function to construct a web socket function for onmessage handling.\n",
  29631. "// Called in the figure constructor.\n",
  29632. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  29633. " return function socket_on_message(evt) {\n",
  29634. " if (evt.data instanceof Blob) {\n",
  29635. " /* FIXME: We get \"Resource interpreted as Image but\n",
  29636. " * transferred with MIME type text/plain:\" errors on\n",
  29637. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  29638. " * to be part of the websocket stream */\n",
  29639. " evt.data.type = \"image/png\";\n",
  29640. "\n",
  29641. " /* Free the memory for the previous frames */\n",
  29642. " if (fig.imageObj.src) {\n",
  29643. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  29644. " fig.imageObj.src);\n",
  29645. " }\n",
  29646. "\n",
  29647. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  29648. " evt.data);\n",
  29649. " fig.updated_canvas_event();\n",
  29650. " fig.waiting = false;\n",
  29651. " return;\n",
  29652. " }\n",
  29653. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  29654. " fig.imageObj.src = evt.data;\n",
  29655. " fig.updated_canvas_event();\n",
  29656. " fig.waiting = false;\n",
  29657. " return;\n",
  29658. " }\n",
  29659. "\n",
  29660. " var msg = JSON.parse(evt.data);\n",
  29661. " var msg_type = msg['type'];\n",
  29662. "\n",
  29663. " // Call the \"handle_{type}\" callback, which takes\n",
  29664. " // the figure and JSON message as its only arguments.\n",
  29665. " try {\n",
  29666. " var callback = fig[\"handle_\" + msg_type];\n",
  29667. " } catch (e) {\n",
  29668. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  29669. " return;\n",
  29670. " }\n",
  29671. "\n",
  29672. " if (callback) {\n",
  29673. " try {\n",
  29674. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  29675. " callback(fig, msg);\n",
  29676. " } catch (e) {\n",
  29677. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  29678. " }\n",
  29679. " }\n",
  29680. " };\n",
  29681. "}\n",
  29682. "\n",
  29683. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  29684. "mpl.findpos = function(e) {\n",
  29685. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  29686. " var targ;\n",
  29687. " if (!e)\n",
  29688. " e = window.event;\n",
  29689. " if (e.target)\n",
  29690. " targ = e.target;\n",
  29691. " else if (e.srcElement)\n",
  29692. " targ = e.srcElement;\n",
  29693. " if (targ.nodeType == 3) // defeat Safari bug\n",
  29694. " targ = targ.parentNode;\n",
  29695. "\n",
  29696. " // jQuery normalizes the pageX and pageY\n",
  29697. " // pageX,Y are the mouse positions relative to the document\n",
  29698. " // offset() returns the position of the element relative to the document\n",
  29699. " var x = e.pageX - $(targ).offset().left;\n",
  29700. " var y = e.pageY - $(targ).offset().top;\n",
  29701. "\n",
  29702. " return {\"x\": x, \"y\": y};\n",
  29703. "};\n",
  29704. "\n",
  29705. "/*\n",
  29706. " * return a copy of an object with only non-object keys\n",
  29707. " * we need this to avoid circular references\n",
  29708. " * http://stackoverflow.com/a/24161582/3208463\n",
  29709. " */\n",
  29710. "function simpleKeys (original) {\n",
  29711. " return Object.keys(original).reduce(function (obj, key) {\n",
  29712. " if (typeof original[key] !== 'object')\n",
  29713. " obj[key] = original[key]\n",
  29714. " return obj;\n",
  29715. " }, {});\n",
  29716. "}\n",
  29717. "\n",
  29718. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  29719. " var canvas_pos = mpl.findpos(event)\n",
  29720. "\n",
  29721. " if (name === 'button_press')\n",
  29722. " {\n",
  29723. " this.canvas.focus();\n",
  29724. " this.canvas_div.focus();\n",
  29725. " }\n",
  29726. "\n",
  29727. " var x = canvas_pos.x * mpl.ratio;\n",
  29728. " var y = canvas_pos.y * mpl.ratio;\n",
  29729. "\n",
  29730. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  29731. " step: event.step,\n",
  29732. " guiEvent: simpleKeys(event)});\n",
  29733. "\n",
  29734. " /* This prevents the web browser from automatically changing to\n",
  29735. " * the text insertion cursor when the button is pressed. We want\n",
  29736. " * to control all of the cursor setting manually through the\n",
  29737. " * 'cursor' event from matplotlib */\n",
  29738. " event.preventDefault();\n",
  29739. " return false;\n",
  29740. "}\n",
  29741. "\n",
  29742. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  29743. " // Handle any extra behaviour associated with a key event\n",
  29744. "}\n",
  29745. "\n",
  29746. "mpl.figure.prototype.key_event = function(event, name) {\n",
  29747. "\n",
  29748. " // Prevent repeat events\n",
  29749. " if (name == 'key_press')\n",
  29750. " {\n",
  29751. " if (event.which === this._key)\n",
  29752. " return;\n",
  29753. " else\n",
  29754. " this._key = event.which;\n",
  29755. " }\n",
  29756. " if (name == 'key_release')\n",
  29757. " this._key = null;\n",
  29758. "\n",
  29759. " var value = '';\n",
  29760. " if (event.ctrlKey && event.which != 17)\n",
  29761. " value += \"ctrl+\";\n",
  29762. " if (event.altKey && event.which != 18)\n",
  29763. " value += \"alt+\";\n",
  29764. " if (event.shiftKey && event.which != 16)\n",
  29765. " value += \"shift+\";\n",
  29766. "\n",
  29767. " value += 'k';\n",
  29768. " value += event.which.toString();\n",
  29769. "\n",
  29770. " this._key_event_extra(event, name);\n",
  29771. "\n",
  29772. " this.send_message(name, {key: value,\n",
  29773. " guiEvent: simpleKeys(event)});\n",
  29774. " return false;\n",
  29775. "}\n",
  29776. "\n",
  29777. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  29778. " if (name == 'download') {\n",
  29779. " this.handle_save(this, null);\n",
  29780. " } else {\n",
  29781. " this.send_message(\"toolbar_button\", {name: name});\n",
  29782. " }\n",
  29783. "};\n",
  29784. "\n",
  29785. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  29786. " this.message.textContent = tooltip;\n",
  29787. "};\n",
  29788. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  29789. "\n",
  29790. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  29791. "\n",
  29792. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  29793. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  29794. " // object with the appropriate methods. Currently this is a non binary\n",
  29795. " // socket, so there is still some room for performance tuning.\n",
  29796. " var ws = {};\n",
  29797. "\n",
  29798. " ws.close = function() {\n",
  29799. " comm.close()\n",
  29800. " };\n",
  29801. " ws.send = function(m) {\n",
  29802. " //console.log('sending', m);\n",
  29803. " comm.send(m);\n",
  29804. " };\n",
  29805. " // Register the callback with on_msg.\n",
  29806. " comm.on_msg(function(msg) {\n",
  29807. " //console.log('receiving', msg['content']['data'], msg);\n",
  29808. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  29809. " ws.onmessage(msg['content']['data'])\n",
  29810. " });\n",
  29811. " return ws;\n",
  29812. "}\n",
  29813. "\n",
  29814. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  29815. " // This is the function which gets called when the mpl process\n",
  29816. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  29817. "\n",
  29818. " var id = msg.content.data.id;\n",
  29819. " // Get hold of the div created by the display call when the Comm\n",
  29820. " // socket was opened in Python.\n",
  29821. " var element = $(\"#\" + id);\n",
  29822. " var ws_proxy = comm_websocket_adapter(comm)\n",
  29823. "\n",
  29824. " function ondownload(figure, format) {\n",
  29825. " window.open(figure.imageObj.src);\n",
  29826. " }\n",
  29827. "\n",
  29828. " var fig = new mpl.figure(id, ws_proxy,\n",
  29829. " ondownload,\n",
  29830. " element.get(0));\n",
  29831. "\n",
  29832. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  29833. " // web socket which is closed, not our websocket->open comm proxy.\n",
  29834. " ws_proxy.onopen();\n",
  29835. "\n",
  29836. " fig.parent_element = element.get(0);\n",
  29837. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  29838. " if (!fig.cell_info) {\n",
  29839. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  29840. " return;\n",
  29841. " }\n",
  29842. "\n",
  29843. " var output_index = fig.cell_info[2]\n",
  29844. " var cell = fig.cell_info[0];\n",
  29845. "\n",
  29846. "};\n",
  29847. "\n",
  29848. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  29849. " var width = fig.canvas.width/mpl.ratio\n",
  29850. " fig.root.unbind('remove')\n",
  29851. "\n",
  29852. " // Update the output cell to use the data from the current canvas.\n",
  29853. " fig.push_to_output();\n",
  29854. " var dataURL = fig.canvas.toDataURL();\n",
  29855. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  29856. " // the notebook keyboard shortcuts fail.\n",
  29857. " IPython.keyboard_manager.enable()\n",
  29858. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  29859. " fig.close_ws(fig, msg);\n",
  29860. "}\n",
  29861. "\n",
  29862. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  29863. " fig.send_message('closing', msg);\n",
  29864. " // fig.ws.close()\n",
  29865. "}\n",
  29866. "\n",
  29867. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  29868. " // Turn the data on the canvas into data in the output cell.\n",
  29869. " var width = this.canvas.width/mpl.ratio\n",
  29870. " var dataURL = this.canvas.toDataURL();\n",
  29871. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  29872. "}\n",
  29873. "\n",
  29874. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  29875. " // Tell IPython that the notebook contents must change.\n",
  29876. " IPython.notebook.set_dirty(true);\n",
  29877. " this.send_message(\"ack\", {});\n",
  29878. " var fig = this;\n",
  29879. " // Wait a second, then push the new image to the DOM so\n",
  29880. " // that it is saved nicely (might be nice to debounce this).\n",
  29881. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  29882. "}\n",
  29883. "\n",
  29884. "mpl.figure.prototype._init_toolbar = function() {\n",
  29885. " var fig = this;\n",
  29886. "\n",
  29887. " var nav_element = $('<div/>')\n",
  29888. " nav_element.attr('style', 'width: 100%');\n",
  29889. " this.root.append(nav_element);\n",
  29890. "\n",
  29891. " // Define a callback function for later on.\n",
  29892. " function toolbar_event(event) {\n",
  29893. " return fig.toolbar_button_onclick(event['data']);\n",
  29894. " }\n",
  29895. " function toolbar_mouse_event(event) {\n",
  29896. " return fig.toolbar_button_onmouseover(event['data']);\n",
  29897. " }\n",
  29898. "\n",
  29899. " for(var toolbar_ind in mpl.toolbar_items){\n",
  29900. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  29901. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  29902. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  29903. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  29904. "\n",
  29905. " if (!name) { continue; };\n",
  29906. "\n",
  29907. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  29908. " button.click(method_name, toolbar_event);\n",
  29909. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  29910. " nav_element.append(button);\n",
  29911. " }\n",
  29912. "\n",
  29913. " // Add the status bar.\n",
  29914. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  29915. " nav_element.append(status_bar);\n",
  29916. " this.message = status_bar[0];\n",
  29917. "\n",
  29918. " // Add the close button to the window.\n",
  29919. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  29920. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  29921. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  29922. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  29923. " buttongrp.append(button);\n",
  29924. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  29925. " titlebar.prepend(buttongrp);\n",
  29926. "}\n",
  29927. "\n",
  29928. "mpl.figure.prototype._root_extra_style = function(el){\n",
  29929. " var fig = this\n",
  29930. " el.on(\"remove\", function(){\n",
  29931. "\tfig.close_ws(fig, {});\n",
  29932. " });\n",
  29933. "}\n",
  29934. "\n",
  29935. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  29936. " // this is important to make the div 'focusable\n",
  29937. " el.attr('tabindex', 0)\n",
  29938. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  29939. " // off when our div gets focus\n",
  29940. "\n",
  29941. " // location in version 3\n",
  29942. " if (IPython.notebook.keyboard_manager) {\n",
  29943. " IPython.notebook.keyboard_manager.register_events(el);\n",
  29944. " }\n",
  29945. " else {\n",
  29946. " // location in version 2\n",
  29947. " IPython.keyboard_manager.register_events(el);\n",
  29948. " }\n",
  29949. "\n",
  29950. "}\n",
  29951. "\n",
  29952. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  29953. " var manager = IPython.notebook.keyboard_manager;\n",
  29954. " if (!manager)\n",
  29955. " manager = IPython.keyboard_manager;\n",
  29956. "\n",
  29957. " // Check for shift+enter\n",
  29958. " if (event.shiftKey && event.which == 13) {\n",
  29959. " this.canvas_div.blur();\n",
  29960. " event.shiftKey = false;\n",
  29961. " // Send a \"J\" for go to next cell\n",
  29962. " event.which = 74;\n",
  29963. " event.keyCode = 74;\n",
  29964. " manager.command_mode();\n",
  29965. " manager.handle_keydown(event);\n",
  29966. " }\n",
  29967. "}\n",
  29968. "\n",
  29969. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  29970. " fig.ondownload(fig, null);\n",
  29971. "}\n",
  29972. "\n",
  29973. "\n",
  29974. "mpl.find_output_cell = function(html_output) {\n",
  29975. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  29976. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  29977. " // IPython event is triggered only after the cells have been serialised, which for\n",
  29978. " // our purposes (turning an active figure into a static one), is too late.\n",
  29979. " var cells = IPython.notebook.get_cells();\n",
  29980. " var ncells = cells.length;\n",
  29981. " for (var i=0; i<ncells; i++) {\n",
  29982. " var cell = cells[i];\n",
  29983. " if (cell.cell_type === 'code'){\n",
  29984. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  29985. " var data = cell.output_area.outputs[j];\n",
  29986. " if (data.data) {\n",
  29987. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  29988. " data = data.data;\n",
  29989. " }\n",
  29990. " if (data['text/html'] == html_output) {\n",
  29991. " return [cell, data, j];\n",
  29992. " }\n",
  29993. " }\n",
  29994. " }\n",
  29995. " }\n",
  29996. "}\n",
  29997. "\n",
  29998. "// Register the function which deals with the matplotlib target/channel.\n",
  29999. "// The kernel may be null if the page has been refreshed.\n",
  30000. "if (IPython.notebook.kernel != null) {\n",
  30001. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  30002. "}\n"
  30003. ],
  30004. "text/plain": [
  30005. "<IPython.core.display.Javascript object>"
  30006. ]
  30007. },
  30008. "metadata": {},
  30009. "output_type": "display_data"
  30010. },
  30011. {
  30012. "data": {
  30013. "text/html": [
  30014. "<img src=\"data:image/png;base64,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5KHxfrcn2TTl97hmPL8nyc4kOzI87XB5ysc/GgaYJKk6AwxgcSxlGEKz2jXlPq9LckeSHyR5JskDSd6d5NRVfp8rMjw98ekMrxW7L8m2OTz+xACTJJVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAEshnOSXJXk00keTvJMkqeS3J3k95KcMuN+lya5I8kT432+muTaJKeu8ntdnuTO8ePvS3Jvkm3r/QRGBpgkqToDDGAx/H6S5SSPJvnbJDcm+WSSJ8fjn0qyacV93pzkQIYR9YkkNyd5aLz97TN+n6vH83uS7EyyI8nu8dj2OXweBpgkqToDDGAxXJbkirz4O10/l+R/Mgyk35o4fmaS7yd5LslrJ46fnuSL4+3f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\" width=\"432\">"
  30015. ],
  30016. "text/plain": [
  30017. "<IPython.core.display.HTML object>"
  30018. ]
  30019. },
  30020. "metadata": {},
  30021. "output_type": "display_data"
  30022. },
  30023. {
  30024. "name": "stdout",
  30025. "output_type": "stream",
  30026. "text": [
  30027. "0.0 1.0\n",
  30028. "888.43896\n",
  30029. "(372, 309)\n",
  30030. "\n"
  30031. ]
  30032. },
  30033. {
  30034. "data": {
  30035. "application/javascript": [
  30036. "/* Put everything inside the global mpl namespace */\n",
  30037. "window.mpl = {};\n",
  30038. "\n",
  30039. "\n",
  30040. "mpl.get_websocket_type = function() {\n",
  30041. " if (typeof(WebSocket) !== 'undefined') {\n",
  30042. " return WebSocket;\n",
  30043. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  30044. " return MozWebSocket;\n",
  30045. " } else {\n",
  30046. " alert('Your browser does not have WebSocket support.' +\n",
  30047. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  30048. " 'Firefox 4 and 5 are also supported but you ' +\n",
  30049. " 'have to enable WebSockets in about:config.');\n",
  30050. " };\n",
  30051. "}\n",
  30052. "\n",
  30053. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  30054. " this.id = figure_id;\n",
  30055. "\n",
  30056. " this.ws = websocket;\n",
  30057. "\n",
  30058. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  30059. "\n",
  30060. " if (!this.supports_binary) {\n",
  30061. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  30062. " if (warnings) {\n",
  30063. " warnings.style.display = 'block';\n",
  30064. " warnings.textContent = (\n",
  30065. " \"This browser does not support binary websocket messages. \" +\n",
  30066. " \"Performance may be slow.\");\n",
  30067. " }\n",
  30068. " }\n",
  30069. "\n",
  30070. " this.imageObj = new Image();\n",
  30071. "\n",
  30072. " this.context = undefined;\n",
  30073. " this.message = undefined;\n",
  30074. " this.canvas = undefined;\n",
  30075. " this.rubberband_canvas = undefined;\n",
  30076. " this.rubberband_context = undefined;\n",
  30077. " this.format_dropdown = undefined;\n",
  30078. "\n",
  30079. " this.image_mode = 'full';\n",
  30080. "\n",
  30081. " this.root = $('<div/>');\n",
  30082. " this._root_extra_style(this.root)\n",
  30083. " this.root.attr('style', 'display: inline-block');\n",
  30084. "\n",
  30085. " $(parent_element).append(this.root);\n",
  30086. "\n",
  30087. " this._init_header(this);\n",
  30088. " this._init_canvas(this);\n",
  30089. " this._init_toolbar(this);\n",
  30090. "\n",
  30091. " var fig = this;\n",
  30092. "\n",
  30093. " this.waiting = false;\n",
  30094. "\n",
  30095. " this.ws.onopen = function () {\n",
  30096. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  30097. " fig.send_message(\"send_image_mode\", {});\n",
  30098. " if (mpl.ratio != 1) {\n",
  30099. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  30100. " }\n",
  30101. " fig.send_message(\"refresh\", {});\n",
  30102. " }\n",
  30103. "\n",
  30104. " this.imageObj.onload = function() {\n",
  30105. " if (fig.image_mode == 'full') {\n",
  30106. " // Full images could contain transparency (where diff images\n",
  30107. " // almost always do), so we need to clear the canvas so that\n",
  30108. " // there is no ghosting.\n",
  30109. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  30110. " }\n",
  30111. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  30112. " };\n",
  30113. "\n",
  30114. " this.imageObj.onunload = function() {\n",
  30115. " fig.ws.close();\n",
  30116. " }\n",
  30117. "\n",
  30118. " this.ws.onmessage = this._make_on_message_function(this);\n",
  30119. "\n",
  30120. " this.ondownload = ondownload;\n",
  30121. "}\n",
  30122. "\n",
  30123. "mpl.figure.prototype._init_header = function() {\n",
  30124. " var titlebar = $(\n",
  30125. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  30126. " 'ui-helper-clearfix\"/>');\n",
  30127. " var titletext = $(\n",
  30128. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  30129. " 'text-align: center; padding: 3px;\"/>');\n",
  30130. " titlebar.append(titletext)\n",
  30131. " this.root.append(titlebar);\n",
  30132. " this.header = titletext[0];\n",
  30133. "}\n",
  30134. "\n",
  30135. "\n",
  30136. "\n",
  30137. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  30138. "\n",
  30139. "}\n",
  30140. "\n",
  30141. "\n",
  30142. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  30143. "\n",
  30144. "}\n",
  30145. "\n",
  30146. "mpl.figure.prototype._init_canvas = function() {\n",
  30147. " var fig = this;\n",
  30148. "\n",
  30149. " var canvas_div = $('<div/>');\n",
  30150. "\n",
  30151. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  30152. "\n",
  30153. " function canvas_keyboard_event(event) {\n",
  30154. " return fig.key_event(event, event['data']);\n",
  30155. " }\n",
  30156. "\n",
  30157. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  30158. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  30159. " this.canvas_div = canvas_div\n",
  30160. " this._canvas_extra_style(canvas_div)\n",
  30161. " this.root.append(canvas_div);\n",
  30162. "\n",
  30163. " var canvas = $('<canvas/>');\n",
  30164. " canvas.addClass('mpl-canvas');\n",
  30165. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  30166. "\n",
  30167. " this.canvas = canvas[0];\n",
  30168. " this.context = canvas[0].getContext(\"2d\");\n",
  30169. "\n",
  30170. " var backingStore = this.context.backingStorePixelRatio ||\n",
  30171. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  30172. "\tthis.context.mozBackingStorePixelRatio ||\n",
  30173. "\tthis.context.msBackingStorePixelRatio ||\n",
  30174. "\tthis.context.oBackingStorePixelRatio ||\n",
  30175. "\tthis.context.backingStorePixelRatio || 1;\n",
  30176. "\n",
  30177. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  30178. "\n",
  30179. " var rubberband = $('<canvas/>');\n",
  30180. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  30181. "\n",
  30182. " var pass_mouse_events = true;\n",
  30183. "\n",
  30184. " canvas_div.resizable({\n",
  30185. " start: function(event, ui) {\n",
  30186. " pass_mouse_events = false;\n",
  30187. " },\n",
  30188. " resize: function(event, ui) {\n",
  30189. " fig.request_resize(ui.size.width, ui.size.height);\n",
  30190. " },\n",
  30191. " stop: function(event, ui) {\n",
  30192. " pass_mouse_events = true;\n",
  30193. " fig.request_resize(ui.size.width, ui.size.height);\n",
  30194. " },\n",
  30195. " });\n",
  30196. "\n",
  30197. " function mouse_event_fn(event) {\n",
  30198. " if (pass_mouse_events)\n",
  30199. " return fig.mouse_event(event, event['data']);\n",
  30200. " }\n",
  30201. "\n",
  30202. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  30203. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  30204. " // Throttle sequential mouse events to 1 every 20ms.\n",
  30205. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  30206. "\n",
  30207. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  30208. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  30209. "\n",
  30210. " canvas_div.on(\"wheel\", function (event) {\n",
  30211. " event = event.originalEvent;\n",
  30212. " event['data'] = 'scroll'\n",
  30213. " if (event.deltaY < 0) {\n",
  30214. " event.step = 1;\n",
  30215. " } else {\n",
  30216. " event.step = -1;\n",
  30217. " }\n",
  30218. " mouse_event_fn(event);\n",
  30219. " });\n",
  30220. "\n",
  30221. " canvas_div.append(canvas);\n",
  30222. " canvas_div.append(rubberband);\n",
  30223. "\n",
  30224. " this.rubberband = rubberband;\n",
  30225. " this.rubberband_canvas = rubberband[0];\n",
  30226. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  30227. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  30228. "\n",
  30229. " this._resize_canvas = function(width, height) {\n",
  30230. " // Keep the size of the canvas, canvas container, and rubber band\n",
  30231. " // canvas in synch.\n",
  30232. " canvas_div.css('width', width)\n",
  30233. " canvas_div.css('height', height)\n",
  30234. "\n",
  30235. " canvas.attr('width', width * mpl.ratio);\n",
  30236. " canvas.attr('height', height * mpl.ratio);\n",
  30237. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  30238. "\n",
  30239. " rubberband.attr('width', width);\n",
  30240. " rubberband.attr('height', height);\n",
  30241. " }\n",
  30242. "\n",
  30243. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  30244. " // upon first draw.\n",
  30245. " this._resize_canvas(600, 600);\n",
  30246. "\n",
  30247. " // Disable right mouse context menu.\n",
  30248. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  30249. " return false;\n",
  30250. " });\n",
  30251. "\n",
  30252. " function set_focus () {\n",
  30253. " canvas.focus();\n",
  30254. " canvas_div.focus();\n",
  30255. " }\n",
  30256. "\n",
  30257. " window.setTimeout(set_focus, 100);\n",
  30258. "}\n",
  30259. "\n",
  30260. "mpl.figure.prototype._init_toolbar = function() {\n",
  30261. " var fig = this;\n",
  30262. "\n",
  30263. " var nav_element = $('<div/>')\n",
  30264. " nav_element.attr('style', 'width: 100%');\n",
  30265. " this.root.append(nav_element);\n",
  30266. "\n",
  30267. " // Define a callback function for later on.\n",
  30268. " function toolbar_event(event) {\n",
  30269. " return fig.toolbar_button_onclick(event['data']);\n",
  30270. " }\n",
  30271. " function toolbar_mouse_event(event) {\n",
  30272. " return fig.toolbar_button_onmouseover(event['data']);\n",
  30273. " }\n",
  30274. "\n",
  30275. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  30276. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  30277. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  30278. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  30279. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  30280. "\n",
  30281. " if (!name) {\n",
  30282. " // put a spacer in here.\n",
  30283. " continue;\n",
  30284. " }\n",
  30285. " var button = $('<button/>');\n",
  30286. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  30287. " 'ui-button-icon-only');\n",
  30288. " button.attr('role', 'button');\n",
  30289. " button.attr('aria-disabled', 'false');\n",
  30290. " button.click(method_name, toolbar_event);\n",
  30291. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  30292. "\n",
  30293. " var icon_img = $('<span/>');\n",
  30294. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  30295. " icon_img.addClass(image);\n",
  30296. " icon_img.addClass('ui-corner-all');\n",
  30297. "\n",
  30298. " var tooltip_span = $('<span/>');\n",
  30299. " tooltip_span.addClass('ui-button-text');\n",
  30300. " tooltip_span.html(tooltip);\n",
  30301. "\n",
  30302. " button.append(icon_img);\n",
  30303. " button.append(tooltip_span);\n",
  30304. "\n",
  30305. " nav_element.append(button);\n",
  30306. " }\n",
  30307. "\n",
  30308. " var fmt_picker_span = $('<span/>');\n",
  30309. "\n",
  30310. " var fmt_picker = $('<select/>');\n",
  30311. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  30312. " fmt_picker_span.append(fmt_picker);\n",
  30313. " nav_element.append(fmt_picker_span);\n",
  30314. " this.format_dropdown = fmt_picker[0];\n",
  30315. "\n",
  30316. " for (var ind in mpl.extensions) {\n",
  30317. " var fmt = mpl.extensions[ind];\n",
  30318. " var option = $(\n",
  30319. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  30320. " fmt_picker.append(option)\n",
  30321. " }\n",
  30322. "\n",
  30323. " // Add hover states to the ui-buttons\n",
  30324. " $( \".ui-button\" ).hover(\n",
  30325. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  30326. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  30327. " );\n",
  30328. "\n",
  30329. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  30330. " nav_element.append(status_bar);\n",
  30331. " this.message = status_bar[0];\n",
  30332. "}\n",
  30333. "\n",
  30334. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  30335. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  30336. " // which will in turn request a refresh of the image.\n",
  30337. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  30338. "}\n",
  30339. "\n",
  30340. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  30341. " properties['type'] = type;\n",
  30342. " properties['figure_id'] = this.id;\n",
  30343. " this.ws.send(JSON.stringify(properties));\n",
  30344. "}\n",
  30345. "\n",
  30346. "mpl.figure.prototype.send_draw_message = function() {\n",
  30347. " if (!this.waiting) {\n",
  30348. " this.waiting = true;\n",
  30349. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  30350. " }\n",
  30351. "}\n",
  30352. "\n",
  30353. "\n",
  30354. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  30355. " var format_dropdown = fig.format_dropdown;\n",
  30356. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  30357. " fig.ondownload(fig, format);\n",
  30358. "}\n",
  30359. "\n",
  30360. "\n",
  30361. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  30362. " var size = msg['size'];\n",
  30363. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  30364. " fig._resize_canvas(size[0], size[1]);\n",
  30365. " fig.send_message(\"refresh\", {});\n",
  30366. " };\n",
  30367. "}\n",
  30368. "\n",
  30369. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  30370. " var x0 = msg['x0'] / mpl.ratio;\n",
  30371. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  30372. " var x1 = msg['x1'] / mpl.ratio;\n",
  30373. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  30374. " x0 = Math.floor(x0) + 0.5;\n",
  30375. " y0 = Math.floor(y0) + 0.5;\n",
  30376. " x1 = Math.floor(x1) + 0.5;\n",
  30377. " y1 = Math.floor(y1) + 0.5;\n",
  30378. " var min_x = Math.min(x0, x1);\n",
  30379. " var min_y = Math.min(y0, y1);\n",
  30380. " var width = Math.abs(x1 - x0);\n",
  30381. " var height = Math.abs(y1 - y0);\n",
  30382. "\n",
  30383. " fig.rubberband_context.clearRect(\n",
  30384. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  30385. "\n",
  30386. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  30387. "}\n",
  30388. "\n",
  30389. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  30390. " // Updates the figure title.\n",
  30391. " fig.header.textContent = msg['label'];\n",
  30392. "}\n",
  30393. "\n",
  30394. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  30395. " var cursor = msg['cursor'];\n",
  30396. " switch(cursor)\n",
  30397. " {\n",
  30398. " case 0:\n",
  30399. " cursor = 'pointer';\n",
  30400. " break;\n",
  30401. " case 1:\n",
  30402. " cursor = 'default';\n",
  30403. " break;\n",
  30404. " case 2:\n",
  30405. " cursor = 'crosshair';\n",
  30406. " break;\n",
  30407. " case 3:\n",
  30408. " cursor = 'move';\n",
  30409. " break;\n",
  30410. " }\n",
  30411. " fig.rubberband_canvas.style.cursor = cursor;\n",
  30412. "}\n",
  30413. "\n",
  30414. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  30415. " fig.message.textContent = msg['message'];\n",
  30416. "}\n",
  30417. "\n",
  30418. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  30419. " // Request the server to send over a new figure.\n",
  30420. " fig.send_draw_message();\n",
  30421. "}\n",
  30422. "\n",
  30423. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  30424. " fig.image_mode = msg['mode'];\n",
  30425. "}\n",
  30426. "\n",
  30427. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  30428. " // Called whenever the canvas gets updated.\n",
  30429. " this.send_message(\"ack\", {});\n",
  30430. "}\n",
  30431. "\n",
  30432. "// A function to construct a web socket function for onmessage handling.\n",
  30433. "// Called in the figure constructor.\n",
  30434. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  30435. " return function socket_on_message(evt) {\n",
  30436. " if (evt.data instanceof Blob) {\n",
  30437. " /* FIXME: We get \"Resource interpreted as Image but\n",
  30438. " * transferred with MIME type text/plain:\" errors on\n",
  30439. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  30440. " * to be part of the websocket stream */\n",
  30441. " evt.data.type = \"image/png\";\n",
  30442. "\n",
  30443. " /* Free the memory for the previous frames */\n",
  30444. " if (fig.imageObj.src) {\n",
  30445. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  30446. " fig.imageObj.src);\n",
  30447. " }\n",
  30448. "\n",
  30449. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  30450. " evt.data);\n",
  30451. " fig.updated_canvas_event();\n",
  30452. " fig.waiting = false;\n",
  30453. " return;\n",
  30454. " }\n",
  30455. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  30456. " fig.imageObj.src = evt.data;\n",
  30457. " fig.updated_canvas_event();\n",
  30458. " fig.waiting = false;\n",
  30459. " return;\n",
  30460. " }\n",
  30461. "\n",
  30462. " var msg = JSON.parse(evt.data);\n",
  30463. " var msg_type = msg['type'];\n",
  30464. "\n",
  30465. " // Call the \"handle_{type}\" callback, which takes\n",
  30466. " // the figure and JSON message as its only arguments.\n",
  30467. " try {\n",
  30468. " var callback = fig[\"handle_\" + msg_type];\n",
  30469. " } catch (e) {\n",
  30470. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  30471. " return;\n",
  30472. " }\n",
  30473. "\n",
  30474. " if (callback) {\n",
  30475. " try {\n",
  30476. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  30477. " callback(fig, msg);\n",
  30478. " } catch (e) {\n",
  30479. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  30480. " }\n",
  30481. " }\n",
  30482. " };\n",
  30483. "}\n",
  30484. "\n",
  30485. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  30486. "mpl.findpos = function(e) {\n",
  30487. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  30488. " var targ;\n",
  30489. " if (!e)\n",
  30490. " e = window.event;\n",
  30491. " if (e.target)\n",
  30492. " targ = e.target;\n",
  30493. " else if (e.srcElement)\n",
  30494. " targ = e.srcElement;\n",
  30495. " if (targ.nodeType == 3) // defeat Safari bug\n",
  30496. " targ = targ.parentNode;\n",
  30497. "\n",
  30498. " // jQuery normalizes the pageX and pageY\n",
  30499. " // pageX,Y are the mouse positions relative to the document\n",
  30500. " // offset() returns the position of the element relative to the document\n",
  30501. " var x = e.pageX - $(targ).offset().left;\n",
  30502. " var y = e.pageY - $(targ).offset().top;\n",
  30503. "\n",
  30504. " return {\"x\": x, \"y\": y};\n",
  30505. "};\n",
  30506. "\n",
  30507. "/*\n",
  30508. " * return a copy of an object with only non-object keys\n",
  30509. " * we need this to avoid circular references\n",
  30510. " * http://stackoverflow.com/a/24161582/3208463\n",
  30511. " */\n",
  30512. "function simpleKeys (original) {\n",
  30513. " return Object.keys(original).reduce(function (obj, key) {\n",
  30514. " if (typeof original[key] !== 'object')\n",
  30515. " obj[key] = original[key]\n",
  30516. " return obj;\n",
  30517. " }, {});\n",
  30518. "}\n",
  30519. "\n",
  30520. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  30521. " var canvas_pos = mpl.findpos(event)\n",
  30522. "\n",
  30523. " if (name === 'button_press')\n",
  30524. " {\n",
  30525. " this.canvas.focus();\n",
  30526. " this.canvas_div.focus();\n",
  30527. " }\n",
  30528. "\n",
  30529. " var x = canvas_pos.x * mpl.ratio;\n",
  30530. " var y = canvas_pos.y * mpl.ratio;\n",
  30531. "\n",
  30532. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  30533. " step: event.step,\n",
  30534. " guiEvent: simpleKeys(event)});\n",
  30535. "\n",
  30536. " /* This prevents the web browser from automatically changing to\n",
  30537. " * the text insertion cursor when the button is pressed. We want\n",
  30538. " * to control all of the cursor setting manually through the\n",
  30539. " * 'cursor' event from matplotlib */\n",
  30540. " event.preventDefault();\n",
  30541. " return false;\n",
  30542. "}\n",
  30543. "\n",
  30544. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  30545. " // Handle any extra behaviour associated with a key event\n",
  30546. "}\n",
  30547. "\n",
  30548. "mpl.figure.prototype.key_event = function(event, name) {\n",
  30549. "\n",
  30550. " // Prevent repeat events\n",
  30551. " if (name == 'key_press')\n",
  30552. " {\n",
  30553. " if (event.which === this._key)\n",
  30554. " return;\n",
  30555. " else\n",
  30556. " this._key = event.which;\n",
  30557. " }\n",
  30558. " if (name == 'key_release')\n",
  30559. " this._key = null;\n",
  30560. "\n",
  30561. " var value = '';\n",
  30562. " if (event.ctrlKey && event.which != 17)\n",
  30563. " value += \"ctrl+\";\n",
  30564. " if (event.altKey && event.which != 18)\n",
  30565. " value += \"alt+\";\n",
  30566. " if (event.shiftKey && event.which != 16)\n",
  30567. " value += \"shift+\";\n",
  30568. "\n",
  30569. " value += 'k';\n",
  30570. " value += event.which.toString();\n",
  30571. "\n",
  30572. " this._key_event_extra(event, name);\n",
  30573. "\n",
  30574. " this.send_message(name, {key: value,\n",
  30575. " guiEvent: simpleKeys(event)});\n",
  30576. " return false;\n",
  30577. "}\n",
  30578. "\n",
  30579. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  30580. " if (name == 'download') {\n",
  30581. " this.handle_save(this, null);\n",
  30582. " } else {\n",
  30583. " this.send_message(\"toolbar_button\", {name: name});\n",
  30584. " }\n",
  30585. "};\n",
  30586. "\n",
  30587. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  30588. " this.message.textContent = tooltip;\n",
  30589. "};\n",
  30590. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  30591. "\n",
  30592. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  30593. "\n",
  30594. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  30595. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  30596. " // object with the appropriate methods. Currently this is a non binary\n",
  30597. " // socket, so there is still some room for performance tuning.\n",
  30598. " var ws = {};\n",
  30599. "\n",
  30600. " ws.close = function() {\n",
  30601. " comm.close()\n",
  30602. " };\n",
  30603. " ws.send = function(m) {\n",
  30604. " //console.log('sending', m);\n",
  30605. " comm.send(m);\n",
  30606. " };\n",
  30607. " // Register the callback with on_msg.\n",
  30608. " comm.on_msg(function(msg) {\n",
  30609. " //console.log('receiving', msg['content']['data'], msg);\n",
  30610. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  30611. " ws.onmessage(msg['content']['data'])\n",
  30612. " });\n",
  30613. " return ws;\n",
  30614. "}\n",
  30615. "\n",
  30616. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  30617. " // This is the function which gets called when the mpl process\n",
  30618. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  30619. "\n",
  30620. " var id = msg.content.data.id;\n",
  30621. " // Get hold of the div created by the display call when the Comm\n",
  30622. " // socket was opened in Python.\n",
  30623. " var element = $(\"#\" + id);\n",
  30624. " var ws_proxy = comm_websocket_adapter(comm)\n",
  30625. "\n",
  30626. " function ondownload(figure, format) {\n",
  30627. " window.open(figure.imageObj.src);\n",
  30628. " }\n",
  30629. "\n",
  30630. " var fig = new mpl.figure(id, ws_proxy,\n",
  30631. " ondownload,\n",
  30632. " element.get(0));\n",
  30633. "\n",
  30634. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  30635. " // web socket which is closed, not our websocket->open comm proxy.\n",
  30636. " ws_proxy.onopen();\n",
  30637. "\n",
  30638. " fig.parent_element = element.get(0);\n",
  30639. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  30640. " if (!fig.cell_info) {\n",
  30641. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  30642. " return;\n",
  30643. " }\n",
  30644. "\n",
  30645. " var output_index = fig.cell_info[2]\n",
  30646. " var cell = fig.cell_info[0];\n",
  30647. "\n",
  30648. "};\n",
  30649. "\n",
  30650. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  30651. " var width = fig.canvas.width/mpl.ratio\n",
  30652. " fig.root.unbind('remove')\n",
  30653. "\n",
  30654. " // Update the output cell to use the data from the current canvas.\n",
  30655. " fig.push_to_output();\n",
  30656. " var dataURL = fig.canvas.toDataURL();\n",
  30657. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  30658. " // the notebook keyboard shortcuts fail.\n",
  30659. " IPython.keyboard_manager.enable()\n",
  30660. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  30661. " fig.close_ws(fig, msg);\n",
  30662. "}\n",
  30663. "\n",
  30664. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  30665. " fig.send_message('closing', msg);\n",
  30666. " // fig.ws.close()\n",
  30667. "}\n",
  30668. "\n",
  30669. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  30670. " // Turn the data on the canvas into data in the output cell.\n",
  30671. " var width = this.canvas.width/mpl.ratio\n",
  30672. " var dataURL = this.canvas.toDataURL();\n",
  30673. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  30674. "}\n",
  30675. "\n",
  30676. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  30677. " // Tell IPython that the notebook contents must change.\n",
  30678. " IPython.notebook.set_dirty(true);\n",
  30679. " this.send_message(\"ack\", {});\n",
  30680. " var fig = this;\n",
  30681. " // Wait a second, then push the new image to the DOM so\n",
  30682. " // that it is saved nicely (might be nice to debounce this).\n",
  30683. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  30684. "}\n",
  30685. "\n",
  30686. "mpl.figure.prototype._init_toolbar = function() {\n",
  30687. " var fig = this;\n",
  30688. "\n",
  30689. " var nav_element = $('<div/>')\n",
  30690. " nav_element.attr('style', 'width: 100%');\n",
  30691. " this.root.append(nav_element);\n",
  30692. "\n",
  30693. " // Define a callback function for later on.\n",
  30694. " function toolbar_event(event) {\n",
  30695. " return fig.toolbar_button_onclick(event['data']);\n",
  30696. " }\n",
  30697. " function toolbar_mouse_event(event) {\n",
  30698. " return fig.toolbar_button_onmouseover(event['data']);\n",
  30699. " }\n",
  30700. "\n",
  30701. " for(var toolbar_ind in mpl.toolbar_items){\n",
  30702. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  30703. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  30704. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  30705. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  30706. "\n",
  30707. " if (!name) { continue; };\n",
  30708. "\n",
  30709. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  30710. " button.click(method_name, toolbar_event);\n",
  30711. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  30712. " nav_element.append(button);\n",
  30713. " }\n",
  30714. "\n",
  30715. " // Add the status bar.\n",
  30716. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  30717. " nav_element.append(status_bar);\n",
  30718. " this.message = status_bar[0];\n",
  30719. "\n",
  30720. " // Add the close button to the window.\n",
  30721. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  30722. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  30723. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  30724. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  30725. " buttongrp.append(button);\n",
  30726. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  30727. " titlebar.prepend(buttongrp);\n",
  30728. "}\n",
  30729. "\n",
  30730. "mpl.figure.prototype._root_extra_style = function(el){\n",
  30731. " var fig = this\n",
  30732. " el.on(\"remove\", function(){\n",
  30733. "\tfig.close_ws(fig, {});\n",
  30734. " });\n",
  30735. "}\n",
  30736. "\n",
  30737. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  30738. " // this is important to make the div 'focusable\n",
  30739. " el.attr('tabindex', 0)\n",
  30740. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  30741. " // off when our div gets focus\n",
  30742. "\n",
  30743. " // location in version 3\n",
  30744. " if (IPython.notebook.keyboard_manager) {\n",
  30745. " IPython.notebook.keyboard_manager.register_events(el);\n",
  30746. " }\n",
  30747. " else {\n",
  30748. " // location in version 2\n",
  30749. " IPython.keyboard_manager.register_events(el);\n",
  30750. " }\n",
  30751. "\n",
  30752. "}\n",
  30753. "\n",
  30754. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  30755. " var manager = IPython.notebook.keyboard_manager;\n",
  30756. " if (!manager)\n",
  30757. " manager = IPython.keyboard_manager;\n",
  30758. "\n",
  30759. " // Check for shift+enter\n",
  30760. " if (event.shiftKey && event.which == 13) {\n",
  30761. " this.canvas_div.blur();\n",
  30762. " event.shiftKey = false;\n",
  30763. " // Send a \"J\" for go to next cell\n",
  30764. " event.which = 74;\n",
  30765. " event.keyCode = 74;\n",
  30766. " manager.command_mode();\n",
  30767. " manager.handle_keydown(event);\n",
  30768. " }\n",
  30769. "}\n",
  30770. "\n",
  30771. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  30772. " fig.ondownload(fig, null);\n",
  30773. "}\n",
  30774. "\n",
  30775. "\n",
  30776. "mpl.find_output_cell = function(html_output) {\n",
  30777. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  30778. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  30779. " // IPython event is triggered only after the cells have been serialised, which for\n",
  30780. " // our purposes (turning an active figure into a static one), is too late.\n",
  30781. " var cells = IPython.notebook.get_cells();\n",
  30782. " var ncells = cells.length;\n",
  30783. " for (var i=0; i<ncells; i++) {\n",
  30784. " var cell = cells[i];\n",
  30785. " if (cell.cell_type === 'code'){\n",
  30786. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  30787. " var data = cell.output_area.outputs[j];\n",
  30788. " if (data.data) {\n",
  30789. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  30790. " data = data.data;\n",
  30791. " }\n",
  30792. " if (data['text/html'] == html_output) {\n",
  30793. " return [cell, data, j];\n",
  30794. " }\n",
  30795. " }\n",
  30796. " }\n",
  30797. " }\n",
  30798. "}\n",
  30799. "\n",
  30800. "// Register the function which deals with the matplotlib target/channel.\n",
  30801. "// The kernel may be null if the page has been refreshed.\n",
  30802. "if (IPython.notebook.kernel != null) {\n",
  30803. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  30804. "}\n"
  30805. ],
  30806. "text/plain": [
  30807. "<IPython.core.display.Javascript object>"
  30808. ]
  30809. },
  30810. "metadata": {},
  30811. "output_type": "display_data"
  30812. },
  30813. {
  30814. "data": {
  30815. "text/html": [
  30816. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  30817. ],
  30818. "text/plain": [
  30819. "<IPython.core.display.HTML object>"
  30820. ]
  30821. },
  30822. "metadata": {},
  30823. "output_type": "display_data"
  30824. },
  30825. {
  30826. "name": "stdout",
  30827. "output_type": "stream",
  30828. "text": [
  30829. "-0.220452 4.805774\n",
  30830. "18979.846\n",
  30831. "(244, 207)\n",
  30832. "\n"
  30833. ]
  30834. },
  30835. {
  30836. "data": {
  30837. "application/javascript": [
  30838. "/* Put everything inside the global mpl namespace */\n",
  30839. "window.mpl = {};\n",
  30840. "\n",
  30841. "\n",
  30842. "mpl.get_websocket_type = function() {\n",
  30843. " if (typeof(WebSocket) !== 'undefined') {\n",
  30844. " return WebSocket;\n",
  30845. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  30846. " return MozWebSocket;\n",
  30847. " } else {\n",
  30848. " alert('Your browser does not have WebSocket support.' +\n",
  30849. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  30850. " 'Firefox 4 and 5 are also supported but you ' +\n",
  30851. " 'have to enable WebSockets in about:config.');\n",
  30852. " };\n",
  30853. "}\n",
  30854. "\n",
  30855. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  30856. " this.id = figure_id;\n",
  30857. "\n",
  30858. " this.ws = websocket;\n",
  30859. "\n",
  30860. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  30861. "\n",
  30862. " if (!this.supports_binary) {\n",
  30863. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  30864. " if (warnings) {\n",
  30865. " warnings.style.display = 'block';\n",
  30866. " warnings.textContent = (\n",
  30867. " \"This browser does not support binary websocket messages. \" +\n",
  30868. " \"Performance may be slow.\");\n",
  30869. " }\n",
  30870. " }\n",
  30871. "\n",
  30872. " this.imageObj = new Image();\n",
  30873. "\n",
  30874. " this.context = undefined;\n",
  30875. " this.message = undefined;\n",
  30876. " this.canvas = undefined;\n",
  30877. " this.rubberband_canvas = undefined;\n",
  30878. " this.rubberband_context = undefined;\n",
  30879. " this.format_dropdown = undefined;\n",
  30880. "\n",
  30881. " this.image_mode = 'full';\n",
  30882. "\n",
  30883. " this.root = $('<div/>');\n",
  30884. " this._root_extra_style(this.root)\n",
  30885. " this.root.attr('style', 'display: inline-block');\n",
  30886. "\n",
  30887. " $(parent_element).append(this.root);\n",
  30888. "\n",
  30889. " this._init_header(this);\n",
  30890. " this._init_canvas(this);\n",
  30891. " this._init_toolbar(this);\n",
  30892. "\n",
  30893. " var fig = this;\n",
  30894. "\n",
  30895. " this.waiting = false;\n",
  30896. "\n",
  30897. " this.ws.onopen = function () {\n",
  30898. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  30899. " fig.send_message(\"send_image_mode\", {});\n",
  30900. " if (mpl.ratio != 1) {\n",
  30901. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  30902. " }\n",
  30903. " fig.send_message(\"refresh\", {});\n",
  30904. " }\n",
  30905. "\n",
  30906. " this.imageObj.onload = function() {\n",
  30907. " if (fig.image_mode == 'full') {\n",
  30908. " // Full images could contain transparency (where diff images\n",
  30909. " // almost always do), so we need to clear the canvas so that\n",
  30910. " // there is no ghosting.\n",
  30911. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  30912. " }\n",
  30913. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  30914. " };\n",
  30915. "\n",
  30916. " this.imageObj.onunload = function() {\n",
  30917. " fig.ws.close();\n",
  30918. " }\n",
  30919. "\n",
  30920. " this.ws.onmessage = this._make_on_message_function(this);\n",
  30921. "\n",
  30922. " this.ondownload = ondownload;\n",
  30923. "}\n",
  30924. "\n",
  30925. "mpl.figure.prototype._init_header = function() {\n",
  30926. " var titlebar = $(\n",
  30927. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  30928. " 'ui-helper-clearfix\"/>');\n",
  30929. " var titletext = $(\n",
  30930. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  30931. " 'text-align: center; padding: 3px;\"/>');\n",
  30932. " titlebar.append(titletext)\n",
  30933. " this.root.append(titlebar);\n",
  30934. " this.header = titletext[0];\n",
  30935. "}\n",
  30936. "\n",
  30937. "\n",
  30938. "\n",
  30939. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  30940. "\n",
  30941. "}\n",
  30942. "\n",
  30943. "\n",
  30944. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  30945. "\n",
  30946. "}\n",
  30947. "\n",
  30948. "mpl.figure.prototype._init_canvas = function() {\n",
  30949. " var fig = this;\n",
  30950. "\n",
  30951. " var canvas_div = $('<div/>');\n",
  30952. "\n",
  30953. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  30954. "\n",
  30955. " function canvas_keyboard_event(event) {\n",
  30956. " return fig.key_event(event, event['data']);\n",
  30957. " }\n",
  30958. "\n",
  30959. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  30960. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  30961. " this.canvas_div = canvas_div\n",
  30962. " this._canvas_extra_style(canvas_div)\n",
  30963. " this.root.append(canvas_div);\n",
  30964. "\n",
  30965. " var canvas = $('<canvas/>');\n",
  30966. " canvas.addClass('mpl-canvas');\n",
  30967. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  30968. "\n",
  30969. " this.canvas = canvas[0];\n",
  30970. " this.context = canvas[0].getContext(\"2d\");\n",
  30971. "\n",
  30972. " var backingStore = this.context.backingStorePixelRatio ||\n",
  30973. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  30974. "\tthis.context.mozBackingStorePixelRatio ||\n",
  30975. "\tthis.context.msBackingStorePixelRatio ||\n",
  30976. "\tthis.context.oBackingStorePixelRatio ||\n",
  30977. "\tthis.context.backingStorePixelRatio || 1;\n",
  30978. "\n",
  30979. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  30980. "\n",
  30981. " var rubberband = $('<canvas/>');\n",
  30982. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  30983. "\n",
  30984. " var pass_mouse_events = true;\n",
  30985. "\n",
  30986. " canvas_div.resizable({\n",
  30987. " start: function(event, ui) {\n",
  30988. " pass_mouse_events = false;\n",
  30989. " },\n",
  30990. " resize: function(event, ui) {\n",
  30991. " fig.request_resize(ui.size.width, ui.size.height);\n",
  30992. " },\n",
  30993. " stop: function(event, ui) {\n",
  30994. " pass_mouse_events = true;\n",
  30995. " fig.request_resize(ui.size.width, ui.size.height);\n",
  30996. " },\n",
  30997. " });\n",
  30998. "\n",
  30999. " function mouse_event_fn(event) {\n",
  31000. " if (pass_mouse_events)\n",
  31001. " return fig.mouse_event(event, event['data']);\n",
  31002. " }\n",
  31003. "\n",
  31004. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  31005. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  31006. " // Throttle sequential mouse events to 1 every 20ms.\n",
  31007. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  31008. "\n",
  31009. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  31010. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  31011. "\n",
  31012. " canvas_div.on(\"wheel\", function (event) {\n",
  31013. " event = event.originalEvent;\n",
  31014. " event['data'] = 'scroll'\n",
  31015. " if (event.deltaY < 0) {\n",
  31016. " event.step = 1;\n",
  31017. " } else {\n",
  31018. " event.step = -1;\n",
  31019. " }\n",
  31020. " mouse_event_fn(event);\n",
  31021. " });\n",
  31022. "\n",
  31023. " canvas_div.append(canvas);\n",
  31024. " canvas_div.append(rubberband);\n",
  31025. "\n",
  31026. " this.rubberband = rubberband;\n",
  31027. " this.rubberband_canvas = rubberband[0];\n",
  31028. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  31029. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  31030. "\n",
  31031. " this._resize_canvas = function(width, height) {\n",
  31032. " // Keep the size of the canvas, canvas container, and rubber band\n",
  31033. " // canvas in synch.\n",
  31034. " canvas_div.css('width', width)\n",
  31035. " canvas_div.css('height', height)\n",
  31036. "\n",
  31037. " canvas.attr('width', width * mpl.ratio);\n",
  31038. " canvas.attr('height', height * mpl.ratio);\n",
  31039. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  31040. "\n",
  31041. " rubberband.attr('width', width);\n",
  31042. " rubberband.attr('height', height);\n",
  31043. " }\n",
  31044. "\n",
  31045. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  31046. " // upon first draw.\n",
  31047. " this._resize_canvas(600, 600);\n",
  31048. "\n",
  31049. " // Disable right mouse context menu.\n",
  31050. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  31051. " return false;\n",
  31052. " });\n",
  31053. "\n",
  31054. " function set_focus () {\n",
  31055. " canvas.focus();\n",
  31056. " canvas_div.focus();\n",
  31057. " }\n",
  31058. "\n",
  31059. " window.setTimeout(set_focus, 100);\n",
  31060. "}\n",
  31061. "\n",
  31062. "mpl.figure.prototype._init_toolbar = function() {\n",
  31063. " var fig = this;\n",
  31064. "\n",
  31065. " var nav_element = $('<div/>')\n",
  31066. " nav_element.attr('style', 'width: 100%');\n",
  31067. " this.root.append(nav_element);\n",
  31068. "\n",
  31069. " // Define a callback function for later on.\n",
  31070. " function toolbar_event(event) {\n",
  31071. " return fig.toolbar_button_onclick(event['data']);\n",
  31072. " }\n",
  31073. " function toolbar_mouse_event(event) {\n",
  31074. " return fig.toolbar_button_onmouseover(event['data']);\n",
  31075. " }\n",
  31076. "\n",
  31077. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  31078. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  31079. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  31080. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  31081. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  31082. "\n",
  31083. " if (!name) {\n",
  31084. " // put a spacer in here.\n",
  31085. " continue;\n",
  31086. " }\n",
  31087. " var button = $('<button/>');\n",
  31088. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  31089. " 'ui-button-icon-only');\n",
  31090. " button.attr('role', 'button');\n",
  31091. " button.attr('aria-disabled', 'false');\n",
  31092. " button.click(method_name, toolbar_event);\n",
  31093. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  31094. "\n",
  31095. " var icon_img = $('<span/>');\n",
  31096. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  31097. " icon_img.addClass(image);\n",
  31098. " icon_img.addClass('ui-corner-all');\n",
  31099. "\n",
  31100. " var tooltip_span = $('<span/>');\n",
  31101. " tooltip_span.addClass('ui-button-text');\n",
  31102. " tooltip_span.html(tooltip);\n",
  31103. "\n",
  31104. " button.append(icon_img);\n",
  31105. " button.append(tooltip_span);\n",
  31106. "\n",
  31107. " nav_element.append(button);\n",
  31108. " }\n",
  31109. "\n",
  31110. " var fmt_picker_span = $('<span/>');\n",
  31111. "\n",
  31112. " var fmt_picker = $('<select/>');\n",
  31113. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  31114. " fmt_picker_span.append(fmt_picker);\n",
  31115. " nav_element.append(fmt_picker_span);\n",
  31116. " this.format_dropdown = fmt_picker[0];\n",
  31117. "\n",
  31118. " for (var ind in mpl.extensions) {\n",
  31119. " var fmt = mpl.extensions[ind];\n",
  31120. " var option = $(\n",
  31121. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  31122. " fmt_picker.append(option)\n",
  31123. " }\n",
  31124. "\n",
  31125. " // Add hover states to the ui-buttons\n",
  31126. " $( \".ui-button\" ).hover(\n",
  31127. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  31128. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  31129. " );\n",
  31130. "\n",
  31131. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  31132. " nav_element.append(status_bar);\n",
  31133. " this.message = status_bar[0];\n",
  31134. "}\n",
  31135. "\n",
  31136. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  31137. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  31138. " // which will in turn request a refresh of the image.\n",
  31139. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  31140. "}\n",
  31141. "\n",
  31142. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  31143. " properties['type'] = type;\n",
  31144. " properties['figure_id'] = this.id;\n",
  31145. " this.ws.send(JSON.stringify(properties));\n",
  31146. "}\n",
  31147. "\n",
  31148. "mpl.figure.prototype.send_draw_message = function() {\n",
  31149. " if (!this.waiting) {\n",
  31150. " this.waiting = true;\n",
  31151. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  31152. " }\n",
  31153. "}\n",
  31154. "\n",
  31155. "\n",
  31156. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  31157. " var format_dropdown = fig.format_dropdown;\n",
  31158. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  31159. " fig.ondownload(fig, format);\n",
  31160. "}\n",
  31161. "\n",
  31162. "\n",
  31163. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  31164. " var size = msg['size'];\n",
  31165. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  31166. " fig._resize_canvas(size[0], size[1]);\n",
  31167. " fig.send_message(\"refresh\", {});\n",
  31168. " };\n",
  31169. "}\n",
  31170. "\n",
  31171. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  31172. " var x0 = msg['x0'] / mpl.ratio;\n",
  31173. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  31174. " var x1 = msg['x1'] / mpl.ratio;\n",
  31175. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  31176. " x0 = Math.floor(x0) + 0.5;\n",
  31177. " y0 = Math.floor(y0) + 0.5;\n",
  31178. " x1 = Math.floor(x1) + 0.5;\n",
  31179. " y1 = Math.floor(y1) + 0.5;\n",
  31180. " var min_x = Math.min(x0, x1);\n",
  31181. " var min_y = Math.min(y0, y1);\n",
  31182. " var width = Math.abs(x1 - x0);\n",
  31183. " var height = Math.abs(y1 - y0);\n",
  31184. "\n",
  31185. " fig.rubberband_context.clearRect(\n",
  31186. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  31187. "\n",
  31188. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  31189. "}\n",
  31190. "\n",
  31191. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  31192. " // Updates the figure title.\n",
  31193. " fig.header.textContent = msg['label'];\n",
  31194. "}\n",
  31195. "\n",
  31196. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  31197. " var cursor = msg['cursor'];\n",
  31198. " switch(cursor)\n",
  31199. " {\n",
  31200. " case 0:\n",
  31201. " cursor = 'pointer';\n",
  31202. " break;\n",
  31203. " case 1:\n",
  31204. " cursor = 'default';\n",
  31205. " break;\n",
  31206. " case 2:\n",
  31207. " cursor = 'crosshair';\n",
  31208. " break;\n",
  31209. " case 3:\n",
  31210. " cursor = 'move';\n",
  31211. " break;\n",
  31212. " }\n",
  31213. " fig.rubberband_canvas.style.cursor = cursor;\n",
  31214. "}\n",
  31215. "\n",
  31216. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  31217. " fig.message.textContent = msg['message'];\n",
  31218. "}\n",
  31219. "\n",
  31220. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  31221. " // Request the server to send over a new figure.\n",
  31222. " fig.send_draw_message();\n",
  31223. "}\n",
  31224. "\n",
  31225. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  31226. " fig.image_mode = msg['mode'];\n",
  31227. "}\n",
  31228. "\n",
  31229. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  31230. " // Called whenever the canvas gets updated.\n",
  31231. " this.send_message(\"ack\", {});\n",
  31232. "}\n",
  31233. "\n",
  31234. "// A function to construct a web socket function for onmessage handling.\n",
  31235. "// Called in the figure constructor.\n",
  31236. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  31237. " return function socket_on_message(evt) {\n",
  31238. " if (evt.data instanceof Blob) {\n",
  31239. " /* FIXME: We get \"Resource interpreted as Image but\n",
  31240. " * transferred with MIME type text/plain:\" errors on\n",
  31241. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  31242. " * to be part of the websocket stream */\n",
  31243. " evt.data.type = \"image/png\";\n",
  31244. "\n",
  31245. " /* Free the memory for the previous frames */\n",
  31246. " if (fig.imageObj.src) {\n",
  31247. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  31248. " fig.imageObj.src);\n",
  31249. " }\n",
  31250. "\n",
  31251. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  31252. " evt.data);\n",
  31253. " fig.updated_canvas_event();\n",
  31254. " fig.waiting = false;\n",
  31255. " return;\n",
  31256. " }\n",
  31257. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  31258. " fig.imageObj.src = evt.data;\n",
  31259. " fig.updated_canvas_event();\n",
  31260. " fig.waiting = false;\n",
  31261. " return;\n",
  31262. " }\n",
  31263. "\n",
  31264. " var msg = JSON.parse(evt.data);\n",
  31265. " var msg_type = msg['type'];\n",
  31266. "\n",
  31267. " // Call the \"handle_{type}\" callback, which takes\n",
  31268. " // the figure and JSON message as its only arguments.\n",
  31269. " try {\n",
  31270. " var callback = fig[\"handle_\" + msg_type];\n",
  31271. " } catch (e) {\n",
  31272. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  31273. " return;\n",
  31274. " }\n",
  31275. "\n",
  31276. " if (callback) {\n",
  31277. " try {\n",
  31278. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  31279. " callback(fig, msg);\n",
  31280. " } catch (e) {\n",
  31281. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  31282. " }\n",
  31283. " }\n",
  31284. " };\n",
  31285. "}\n",
  31286. "\n",
  31287. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  31288. "mpl.findpos = function(e) {\n",
  31289. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  31290. " var targ;\n",
  31291. " if (!e)\n",
  31292. " e = window.event;\n",
  31293. " if (e.target)\n",
  31294. " targ = e.target;\n",
  31295. " else if (e.srcElement)\n",
  31296. " targ = e.srcElement;\n",
  31297. " if (targ.nodeType == 3) // defeat Safari bug\n",
  31298. " targ = targ.parentNode;\n",
  31299. "\n",
  31300. " // jQuery normalizes the pageX and pageY\n",
  31301. " // pageX,Y are the mouse positions relative to the document\n",
  31302. " // offset() returns the position of the element relative to the document\n",
  31303. " var x = e.pageX - $(targ).offset().left;\n",
  31304. " var y = e.pageY - $(targ).offset().top;\n",
  31305. "\n",
  31306. " return {\"x\": x, \"y\": y};\n",
  31307. "};\n",
  31308. "\n",
  31309. "/*\n",
  31310. " * return a copy of an object with only non-object keys\n",
  31311. " * we need this to avoid circular references\n",
  31312. " * http://stackoverflow.com/a/24161582/3208463\n",
  31313. " */\n",
  31314. "function simpleKeys (original) {\n",
  31315. " return Object.keys(original).reduce(function (obj, key) {\n",
  31316. " if (typeof original[key] !== 'object')\n",
  31317. " obj[key] = original[key]\n",
  31318. " return obj;\n",
  31319. " }, {});\n",
  31320. "}\n",
  31321. "\n",
  31322. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  31323. " var canvas_pos = mpl.findpos(event)\n",
  31324. "\n",
  31325. " if (name === 'button_press')\n",
  31326. " {\n",
  31327. " this.canvas.focus();\n",
  31328. " this.canvas_div.focus();\n",
  31329. " }\n",
  31330. "\n",
  31331. " var x = canvas_pos.x * mpl.ratio;\n",
  31332. " var y = canvas_pos.y * mpl.ratio;\n",
  31333. "\n",
  31334. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  31335. " step: event.step,\n",
  31336. " guiEvent: simpleKeys(event)});\n",
  31337. "\n",
  31338. " /* This prevents the web browser from automatically changing to\n",
  31339. " * the text insertion cursor when the button is pressed. We want\n",
  31340. " * to control all of the cursor setting manually through the\n",
  31341. " * 'cursor' event from matplotlib */\n",
  31342. " event.preventDefault();\n",
  31343. " return false;\n",
  31344. "}\n",
  31345. "\n",
  31346. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  31347. " // Handle any extra behaviour associated with a key event\n",
  31348. "}\n",
  31349. "\n",
  31350. "mpl.figure.prototype.key_event = function(event, name) {\n",
  31351. "\n",
  31352. " // Prevent repeat events\n",
  31353. " if (name == 'key_press')\n",
  31354. " {\n",
  31355. " if (event.which === this._key)\n",
  31356. " return;\n",
  31357. " else\n",
  31358. " this._key = event.which;\n",
  31359. " }\n",
  31360. " if (name == 'key_release')\n",
  31361. " this._key = null;\n",
  31362. "\n",
  31363. " var value = '';\n",
  31364. " if (event.ctrlKey && event.which != 17)\n",
  31365. " value += \"ctrl+\";\n",
  31366. " if (event.altKey && event.which != 18)\n",
  31367. " value += \"alt+\";\n",
  31368. " if (event.shiftKey && event.which != 16)\n",
  31369. " value += \"shift+\";\n",
  31370. "\n",
  31371. " value += 'k';\n",
  31372. " value += event.which.toString();\n",
  31373. "\n",
  31374. " this._key_event_extra(event, name);\n",
  31375. "\n",
  31376. " this.send_message(name, {key: value,\n",
  31377. " guiEvent: simpleKeys(event)});\n",
  31378. " return false;\n",
  31379. "}\n",
  31380. "\n",
  31381. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  31382. " if (name == 'download') {\n",
  31383. " this.handle_save(this, null);\n",
  31384. " } else {\n",
  31385. " this.send_message(\"toolbar_button\", {name: name});\n",
  31386. " }\n",
  31387. "};\n",
  31388. "\n",
  31389. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  31390. " this.message.textContent = tooltip;\n",
  31391. "};\n",
  31392. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  31393. "\n",
  31394. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  31395. "\n",
  31396. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  31397. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  31398. " // object with the appropriate methods. Currently this is a non binary\n",
  31399. " // socket, so there is still some room for performance tuning.\n",
  31400. " var ws = {};\n",
  31401. "\n",
  31402. " ws.close = function() {\n",
  31403. " comm.close()\n",
  31404. " };\n",
  31405. " ws.send = function(m) {\n",
  31406. " //console.log('sending', m);\n",
  31407. " comm.send(m);\n",
  31408. " };\n",
  31409. " // Register the callback with on_msg.\n",
  31410. " comm.on_msg(function(msg) {\n",
  31411. " //console.log('receiving', msg['content']['data'], msg);\n",
  31412. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  31413. " ws.onmessage(msg['content']['data'])\n",
  31414. " });\n",
  31415. " return ws;\n",
  31416. "}\n",
  31417. "\n",
  31418. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  31419. " // This is the function which gets called when the mpl process\n",
  31420. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  31421. "\n",
  31422. " var id = msg.content.data.id;\n",
  31423. " // Get hold of the div created by the display call when the Comm\n",
  31424. " // socket was opened in Python.\n",
  31425. " var element = $(\"#\" + id);\n",
  31426. " var ws_proxy = comm_websocket_adapter(comm)\n",
  31427. "\n",
  31428. " function ondownload(figure, format) {\n",
  31429. " window.open(figure.imageObj.src);\n",
  31430. " }\n",
  31431. "\n",
  31432. " var fig = new mpl.figure(id, ws_proxy,\n",
  31433. " ondownload,\n",
  31434. " element.get(0));\n",
  31435. "\n",
  31436. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  31437. " // web socket which is closed, not our websocket->open comm proxy.\n",
  31438. " ws_proxy.onopen();\n",
  31439. "\n",
  31440. " fig.parent_element = element.get(0);\n",
  31441. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  31442. " if (!fig.cell_info) {\n",
  31443. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  31444. " return;\n",
  31445. " }\n",
  31446. "\n",
  31447. " var output_index = fig.cell_info[2]\n",
  31448. " var cell = fig.cell_info[0];\n",
  31449. "\n",
  31450. "};\n",
  31451. "\n",
  31452. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  31453. " var width = fig.canvas.width/mpl.ratio\n",
  31454. " fig.root.unbind('remove')\n",
  31455. "\n",
  31456. " // Update the output cell to use the data from the current canvas.\n",
  31457. " fig.push_to_output();\n",
  31458. " var dataURL = fig.canvas.toDataURL();\n",
  31459. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  31460. " // the notebook keyboard shortcuts fail.\n",
  31461. " IPython.keyboard_manager.enable()\n",
  31462. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  31463. " fig.close_ws(fig, msg);\n",
  31464. "}\n",
  31465. "\n",
  31466. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  31467. " fig.send_message('closing', msg);\n",
  31468. " // fig.ws.close()\n",
  31469. "}\n",
  31470. "\n",
  31471. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  31472. " // Turn the data on the canvas into data in the output cell.\n",
  31473. " var width = this.canvas.width/mpl.ratio\n",
  31474. " var dataURL = this.canvas.toDataURL();\n",
  31475. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  31476. "}\n",
  31477. "\n",
  31478. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  31479. " // Tell IPython that the notebook contents must change.\n",
  31480. " IPython.notebook.set_dirty(true);\n",
  31481. " this.send_message(\"ack\", {});\n",
  31482. " var fig = this;\n",
  31483. " // Wait a second, then push the new image to the DOM so\n",
  31484. " // that it is saved nicely (might be nice to debounce this).\n",
  31485. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  31486. "}\n",
  31487. "\n",
  31488. "mpl.figure.prototype._init_toolbar = function() {\n",
  31489. " var fig = this;\n",
  31490. "\n",
  31491. " var nav_element = $('<div/>')\n",
  31492. " nav_element.attr('style', 'width: 100%');\n",
  31493. " this.root.append(nav_element);\n",
  31494. "\n",
  31495. " // Define a callback function for later on.\n",
  31496. " function toolbar_event(event) {\n",
  31497. " return fig.toolbar_button_onclick(event['data']);\n",
  31498. " }\n",
  31499. " function toolbar_mouse_event(event) {\n",
  31500. " return fig.toolbar_button_onmouseover(event['data']);\n",
  31501. " }\n",
  31502. "\n",
  31503. " for(var toolbar_ind in mpl.toolbar_items){\n",
  31504. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  31505. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  31506. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  31507. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  31508. "\n",
  31509. " if (!name) { continue; };\n",
  31510. "\n",
  31511. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  31512. " button.click(method_name, toolbar_event);\n",
  31513. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  31514. " nav_element.append(button);\n",
  31515. " }\n",
  31516. "\n",
  31517. " // Add the status bar.\n",
  31518. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  31519. " nav_element.append(status_bar);\n",
  31520. " this.message = status_bar[0];\n",
  31521. "\n",
  31522. " // Add the close button to the window.\n",
  31523. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  31524. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  31525. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  31526. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  31527. " buttongrp.append(button);\n",
  31528. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  31529. " titlebar.prepend(buttongrp);\n",
  31530. "}\n",
  31531. "\n",
  31532. "mpl.figure.prototype._root_extra_style = function(el){\n",
  31533. " var fig = this\n",
  31534. " el.on(\"remove\", function(){\n",
  31535. "\tfig.close_ws(fig, {});\n",
  31536. " });\n",
  31537. "}\n",
  31538. "\n",
  31539. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  31540. " // this is important to make the div 'focusable\n",
  31541. " el.attr('tabindex', 0)\n",
  31542. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  31543. " // off when our div gets focus\n",
  31544. "\n",
  31545. " // location in version 3\n",
  31546. " if (IPython.notebook.keyboard_manager) {\n",
  31547. " IPython.notebook.keyboard_manager.register_events(el);\n",
  31548. " }\n",
  31549. " else {\n",
  31550. " // location in version 2\n",
  31551. " IPython.keyboard_manager.register_events(el);\n",
  31552. " }\n",
  31553. "\n",
  31554. "}\n",
  31555. "\n",
  31556. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  31557. " var manager = IPython.notebook.keyboard_manager;\n",
  31558. " if (!manager)\n",
  31559. " manager = IPython.keyboard_manager;\n",
  31560. "\n",
  31561. " // Check for shift+enter\n",
  31562. " if (event.shiftKey && event.which == 13) {\n",
  31563. " this.canvas_div.blur();\n",
  31564. " event.shiftKey = false;\n",
  31565. " // Send a \"J\" for go to next cell\n",
  31566. " event.which = 74;\n",
  31567. " event.keyCode = 74;\n",
  31568. " manager.command_mode();\n",
  31569. " manager.handle_keydown(event);\n",
  31570. " }\n",
  31571. "}\n",
  31572. "\n",
  31573. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  31574. " fig.ondownload(fig, null);\n",
  31575. "}\n",
  31576. "\n",
  31577. "\n",
  31578. "mpl.find_output_cell = function(html_output) {\n",
  31579. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  31580. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  31581. " // IPython event is triggered only after the cells have been serialised, which for\n",
  31582. " // our purposes (turning an active figure into a static one), is too late.\n",
  31583. " var cells = IPython.notebook.get_cells();\n",
  31584. " var ncells = cells.length;\n",
  31585. " for (var i=0; i<ncells; i++) {\n",
  31586. " var cell = cells[i];\n",
  31587. " if (cell.cell_type === 'code'){\n",
  31588. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  31589. " var data = cell.output_area.outputs[j];\n",
  31590. " if (data.data) {\n",
  31591. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  31592. " data = data.data;\n",
  31593. " }\n",
  31594. " if (data['text/html'] == html_output) {\n",
  31595. " return [cell, data, j];\n",
  31596. " }\n",
  31597. " }\n",
  31598. " }\n",
  31599. " }\n",
  31600. "}\n",
  31601. "\n",
  31602. "// Register the function which deals with the matplotlib target/channel.\n",
  31603. "// The kernel may be null if the page has been refreshed.\n",
  31604. "if (IPython.notebook.kernel != null) {\n",
  31605. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  31606. "}\n"
  31607. ],
  31608. "text/plain": [
  31609. "<IPython.core.display.Javascript object>"
  31610. ]
  31611. },
  31612. "metadata": {},
  31613. "output_type": "display_data"
  31614. },
  31615. {
  31616. "data": {
  31617. "text/html": [
  31618. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  31619. ],
  31620. "text/plain": [
  31621. "<IPython.core.display.HTML object>"
  31622. ]
  31623. },
  31624. "metadata": {},
  31625. "output_type": "display_data"
  31626. },
  31627. {
  31628. "name": "stdout",
  31629. "output_type": "stream",
  31630. "text": [
  31631. "0.0 1.0\n",
  31632. "660.0\n",
  31633. "(355, 308)\n",
  31634. "\n"
  31635. ]
  31636. },
  31637. {
  31638. "data": {
  31639. "application/javascript": [
  31640. "/* Put everything inside the global mpl namespace */\n",
  31641. "window.mpl = {};\n",
  31642. "\n",
  31643. "\n",
  31644. "mpl.get_websocket_type = function() {\n",
  31645. " if (typeof(WebSocket) !== 'undefined') {\n",
  31646. " return WebSocket;\n",
  31647. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  31648. " return MozWebSocket;\n",
  31649. " } else {\n",
  31650. " alert('Your browser does not have WebSocket support.' +\n",
  31651. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  31652. " 'Firefox 4 and 5 are also supported but you ' +\n",
  31653. " 'have to enable WebSockets in about:config.');\n",
  31654. " };\n",
  31655. "}\n",
  31656. "\n",
  31657. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  31658. " this.id = figure_id;\n",
  31659. "\n",
  31660. " this.ws = websocket;\n",
  31661. "\n",
  31662. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  31663. "\n",
  31664. " if (!this.supports_binary) {\n",
  31665. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  31666. " if (warnings) {\n",
  31667. " warnings.style.display = 'block';\n",
  31668. " warnings.textContent = (\n",
  31669. " \"This browser does not support binary websocket messages. \" +\n",
  31670. " \"Performance may be slow.\");\n",
  31671. " }\n",
  31672. " }\n",
  31673. "\n",
  31674. " this.imageObj = new Image();\n",
  31675. "\n",
  31676. " this.context = undefined;\n",
  31677. " this.message = undefined;\n",
  31678. " this.canvas = undefined;\n",
  31679. " this.rubberband_canvas = undefined;\n",
  31680. " this.rubberband_context = undefined;\n",
  31681. " this.format_dropdown = undefined;\n",
  31682. "\n",
  31683. " this.image_mode = 'full';\n",
  31684. "\n",
  31685. " this.root = $('<div/>');\n",
  31686. " this._root_extra_style(this.root)\n",
  31687. " this.root.attr('style', 'display: inline-block');\n",
  31688. "\n",
  31689. " $(parent_element).append(this.root);\n",
  31690. "\n",
  31691. " this._init_header(this);\n",
  31692. " this._init_canvas(this);\n",
  31693. " this._init_toolbar(this);\n",
  31694. "\n",
  31695. " var fig = this;\n",
  31696. "\n",
  31697. " this.waiting = false;\n",
  31698. "\n",
  31699. " this.ws.onopen = function () {\n",
  31700. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  31701. " fig.send_message(\"send_image_mode\", {});\n",
  31702. " if (mpl.ratio != 1) {\n",
  31703. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  31704. " }\n",
  31705. " fig.send_message(\"refresh\", {});\n",
  31706. " }\n",
  31707. "\n",
  31708. " this.imageObj.onload = function() {\n",
  31709. " if (fig.image_mode == 'full') {\n",
  31710. " // Full images could contain transparency (where diff images\n",
  31711. " // almost always do), so we need to clear the canvas so that\n",
  31712. " // there is no ghosting.\n",
  31713. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  31714. " }\n",
  31715. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  31716. " };\n",
  31717. "\n",
  31718. " this.imageObj.onunload = function() {\n",
  31719. " fig.ws.close();\n",
  31720. " }\n",
  31721. "\n",
  31722. " this.ws.onmessage = this._make_on_message_function(this);\n",
  31723. "\n",
  31724. " this.ondownload = ondownload;\n",
  31725. "}\n",
  31726. "\n",
  31727. "mpl.figure.prototype._init_header = function() {\n",
  31728. " var titlebar = $(\n",
  31729. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  31730. " 'ui-helper-clearfix\"/>');\n",
  31731. " var titletext = $(\n",
  31732. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  31733. " 'text-align: center; padding: 3px;\"/>');\n",
  31734. " titlebar.append(titletext)\n",
  31735. " this.root.append(titlebar);\n",
  31736. " this.header = titletext[0];\n",
  31737. "}\n",
  31738. "\n",
  31739. "\n",
  31740. "\n",
  31741. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  31742. "\n",
  31743. "}\n",
  31744. "\n",
  31745. "\n",
  31746. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  31747. "\n",
  31748. "}\n",
  31749. "\n",
  31750. "mpl.figure.prototype._init_canvas = function() {\n",
  31751. " var fig = this;\n",
  31752. "\n",
  31753. " var canvas_div = $('<div/>');\n",
  31754. "\n",
  31755. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  31756. "\n",
  31757. " function canvas_keyboard_event(event) {\n",
  31758. " return fig.key_event(event, event['data']);\n",
  31759. " }\n",
  31760. "\n",
  31761. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  31762. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  31763. " this.canvas_div = canvas_div\n",
  31764. " this._canvas_extra_style(canvas_div)\n",
  31765. " this.root.append(canvas_div);\n",
  31766. "\n",
  31767. " var canvas = $('<canvas/>');\n",
  31768. " canvas.addClass('mpl-canvas');\n",
  31769. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  31770. "\n",
  31771. " this.canvas = canvas[0];\n",
  31772. " this.context = canvas[0].getContext(\"2d\");\n",
  31773. "\n",
  31774. " var backingStore = this.context.backingStorePixelRatio ||\n",
  31775. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  31776. "\tthis.context.mozBackingStorePixelRatio ||\n",
  31777. "\tthis.context.msBackingStorePixelRatio ||\n",
  31778. "\tthis.context.oBackingStorePixelRatio ||\n",
  31779. "\tthis.context.backingStorePixelRatio || 1;\n",
  31780. "\n",
  31781. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  31782. "\n",
  31783. " var rubberband = $('<canvas/>');\n",
  31784. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  31785. "\n",
  31786. " var pass_mouse_events = true;\n",
  31787. "\n",
  31788. " canvas_div.resizable({\n",
  31789. " start: function(event, ui) {\n",
  31790. " pass_mouse_events = false;\n",
  31791. " },\n",
  31792. " resize: function(event, ui) {\n",
  31793. " fig.request_resize(ui.size.width, ui.size.height);\n",
  31794. " },\n",
  31795. " stop: function(event, ui) {\n",
  31796. " pass_mouse_events = true;\n",
  31797. " fig.request_resize(ui.size.width, ui.size.height);\n",
  31798. " },\n",
  31799. " });\n",
  31800. "\n",
  31801. " function mouse_event_fn(event) {\n",
  31802. " if (pass_mouse_events)\n",
  31803. " return fig.mouse_event(event, event['data']);\n",
  31804. " }\n",
  31805. "\n",
  31806. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  31807. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  31808. " // Throttle sequential mouse events to 1 every 20ms.\n",
  31809. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  31810. "\n",
  31811. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  31812. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  31813. "\n",
  31814. " canvas_div.on(\"wheel\", function (event) {\n",
  31815. " event = event.originalEvent;\n",
  31816. " event['data'] = 'scroll'\n",
  31817. " if (event.deltaY < 0) {\n",
  31818. " event.step = 1;\n",
  31819. " } else {\n",
  31820. " event.step = -1;\n",
  31821. " }\n",
  31822. " mouse_event_fn(event);\n",
  31823. " });\n",
  31824. "\n",
  31825. " canvas_div.append(canvas);\n",
  31826. " canvas_div.append(rubberband);\n",
  31827. "\n",
  31828. " this.rubberband = rubberband;\n",
  31829. " this.rubberband_canvas = rubberband[0];\n",
  31830. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  31831. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  31832. "\n",
  31833. " this._resize_canvas = function(width, height) {\n",
  31834. " // Keep the size of the canvas, canvas container, and rubber band\n",
  31835. " // canvas in synch.\n",
  31836. " canvas_div.css('width', width)\n",
  31837. " canvas_div.css('height', height)\n",
  31838. "\n",
  31839. " canvas.attr('width', width * mpl.ratio);\n",
  31840. " canvas.attr('height', height * mpl.ratio);\n",
  31841. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  31842. "\n",
  31843. " rubberband.attr('width', width);\n",
  31844. " rubberband.attr('height', height);\n",
  31845. " }\n",
  31846. "\n",
  31847. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  31848. " // upon first draw.\n",
  31849. " this._resize_canvas(600, 600);\n",
  31850. "\n",
  31851. " // Disable right mouse context menu.\n",
  31852. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  31853. " return false;\n",
  31854. " });\n",
  31855. "\n",
  31856. " function set_focus () {\n",
  31857. " canvas.focus();\n",
  31858. " canvas_div.focus();\n",
  31859. " }\n",
  31860. "\n",
  31861. " window.setTimeout(set_focus, 100);\n",
  31862. "}\n",
  31863. "\n",
  31864. "mpl.figure.prototype._init_toolbar = function() {\n",
  31865. " var fig = this;\n",
  31866. "\n",
  31867. " var nav_element = $('<div/>')\n",
  31868. " nav_element.attr('style', 'width: 100%');\n",
  31869. " this.root.append(nav_element);\n",
  31870. "\n",
  31871. " // Define a callback function for later on.\n",
  31872. " function toolbar_event(event) {\n",
  31873. " return fig.toolbar_button_onclick(event['data']);\n",
  31874. " }\n",
  31875. " function toolbar_mouse_event(event) {\n",
  31876. " return fig.toolbar_button_onmouseover(event['data']);\n",
  31877. " }\n",
  31878. "\n",
  31879. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  31880. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  31881. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  31882. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  31883. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  31884. "\n",
  31885. " if (!name) {\n",
  31886. " // put a spacer in here.\n",
  31887. " continue;\n",
  31888. " }\n",
  31889. " var button = $('<button/>');\n",
  31890. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  31891. " 'ui-button-icon-only');\n",
  31892. " button.attr('role', 'button');\n",
  31893. " button.attr('aria-disabled', 'false');\n",
  31894. " button.click(method_name, toolbar_event);\n",
  31895. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  31896. "\n",
  31897. " var icon_img = $('<span/>');\n",
  31898. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  31899. " icon_img.addClass(image);\n",
  31900. " icon_img.addClass('ui-corner-all');\n",
  31901. "\n",
  31902. " var tooltip_span = $('<span/>');\n",
  31903. " tooltip_span.addClass('ui-button-text');\n",
  31904. " tooltip_span.html(tooltip);\n",
  31905. "\n",
  31906. " button.append(icon_img);\n",
  31907. " button.append(tooltip_span);\n",
  31908. "\n",
  31909. " nav_element.append(button);\n",
  31910. " }\n",
  31911. "\n",
  31912. " var fmt_picker_span = $('<span/>');\n",
  31913. "\n",
  31914. " var fmt_picker = $('<select/>');\n",
  31915. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  31916. " fmt_picker_span.append(fmt_picker);\n",
  31917. " nav_element.append(fmt_picker_span);\n",
  31918. " this.format_dropdown = fmt_picker[0];\n",
  31919. "\n",
  31920. " for (var ind in mpl.extensions) {\n",
  31921. " var fmt = mpl.extensions[ind];\n",
  31922. " var option = $(\n",
  31923. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  31924. " fmt_picker.append(option)\n",
  31925. " }\n",
  31926. "\n",
  31927. " // Add hover states to the ui-buttons\n",
  31928. " $( \".ui-button\" ).hover(\n",
  31929. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  31930. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  31931. " );\n",
  31932. "\n",
  31933. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  31934. " nav_element.append(status_bar);\n",
  31935. " this.message = status_bar[0];\n",
  31936. "}\n",
  31937. "\n",
  31938. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  31939. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  31940. " // which will in turn request a refresh of the image.\n",
  31941. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  31942. "}\n",
  31943. "\n",
  31944. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  31945. " properties['type'] = type;\n",
  31946. " properties['figure_id'] = this.id;\n",
  31947. " this.ws.send(JSON.stringify(properties));\n",
  31948. "}\n",
  31949. "\n",
  31950. "mpl.figure.prototype.send_draw_message = function() {\n",
  31951. " if (!this.waiting) {\n",
  31952. " this.waiting = true;\n",
  31953. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  31954. " }\n",
  31955. "}\n",
  31956. "\n",
  31957. "\n",
  31958. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  31959. " var format_dropdown = fig.format_dropdown;\n",
  31960. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  31961. " fig.ondownload(fig, format);\n",
  31962. "}\n",
  31963. "\n",
  31964. "\n",
  31965. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  31966. " var size = msg['size'];\n",
  31967. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  31968. " fig._resize_canvas(size[0], size[1]);\n",
  31969. " fig.send_message(\"refresh\", {});\n",
  31970. " };\n",
  31971. "}\n",
  31972. "\n",
  31973. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  31974. " var x0 = msg['x0'] / mpl.ratio;\n",
  31975. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  31976. " var x1 = msg['x1'] / mpl.ratio;\n",
  31977. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  31978. " x0 = Math.floor(x0) + 0.5;\n",
  31979. " y0 = Math.floor(y0) + 0.5;\n",
  31980. " x1 = Math.floor(x1) + 0.5;\n",
  31981. " y1 = Math.floor(y1) + 0.5;\n",
  31982. " var min_x = Math.min(x0, x1);\n",
  31983. " var min_y = Math.min(y0, y1);\n",
  31984. " var width = Math.abs(x1 - x0);\n",
  31985. " var height = Math.abs(y1 - y0);\n",
  31986. "\n",
  31987. " fig.rubberband_context.clearRect(\n",
  31988. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  31989. "\n",
  31990. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  31991. "}\n",
  31992. "\n",
  31993. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  31994. " // Updates the figure title.\n",
  31995. " fig.header.textContent = msg['label'];\n",
  31996. "}\n",
  31997. "\n",
  31998. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  31999. " var cursor = msg['cursor'];\n",
  32000. " switch(cursor)\n",
  32001. " {\n",
  32002. " case 0:\n",
  32003. " cursor = 'pointer';\n",
  32004. " break;\n",
  32005. " case 1:\n",
  32006. " cursor = 'default';\n",
  32007. " break;\n",
  32008. " case 2:\n",
  32009. " cursor = 'crosshair';\n",
  32010. " break;\n",
  32011. " case 3:\n",
  32012. " cursor = 'move';\n",
  32013. " break;\n",
  32014. " }\n",
  32015. " fig.rubberband_canvas.style.cursor = cursor;\n",
  32016. "}\n",
  32017. "\n",
  32018. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  32019. " fig.message.textContent = msg['message'];\n",
  32020. "}\n",
  32021. "\n",
  32022. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  32023. " // Request the server to send over a new figure.\n",
  32024. " fig.send_draw_message();\n",
  32025. "}\n",
  32026. "\n",
  32027. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  32028. " fig.image_mode = msg['mode'];\n",
  32029. "}\n",
  32030. "\n",
  32031. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  32032. " // Called whenever the canvas gets updated.\n",
  32033. " this.send_message(\"ack\", {});\n",
  32034. "}\n",
  32035. "\n",
  32036. "// A function to construct a web socket function for onmessage handling.\n",
  32037. "// Called in the figure constructor.\n",
  32038. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  32039. " return function socket_on_message(evt) {\n",
  32040. " if (evt.data instanceof Blob) {\n",
  32041. " /* FIXME: We get \"Resource interpreted as Image but\n",
  32042. " * transferred with MIME type text/plain:\" errors on\n",
  32043. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  32044. " * to be part of the websocket stream */\n",
  32045. " evt.data.type = \"image/png\";\n",
  32046. "\n",
  32047. " /* Free the memory for the previous frames */\n",
  32048. " if (fig.imageObj.src) {\n",
  32049. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  32050. " fig.imageObj.src);\n",
  32051. " }\n",
  32052. "\n",
  32053. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  32054. " evt.data);\n",
  32055. " fig.updated_canvas_event();\n",
  32056. " fig.waiting = false;\n",
  32057. " return;\n",
  32058. " }\n",
  32059. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  32060. " fig.imageObj.src = evt.data;\n",
  32061. " fig.updated_canvas_event();\n",
  32062. " fig.waiting = false;\n",
  32063. " return;\n",
  32064. " }\n",
  32065. "\n",
  32066. " var msg = JSON.parse(evt.data);\n",
  32067. " var msg_type = msg['type'];\n",
  32068. "\n",
  32069. " // Call the \"handle_{type}\" callback, which takes\n",
  32070. " // the figure and JSON message as its only arguments.\n",
  32071. " try {\n",
  32072. " var callback = fig[\"handle_\" + msg_type];\n",
  32073. " } catch (e) {\n",
  32074. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  32075. " return;\n",
  32076. " }\n",
  32077. "\n",
  32078. " if (callback) {\n",
  32079. " try {\n",
  32080. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  32081. " callback(fig, msg);\n",
  32082. " } catch (e) {\n",
  32083. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  32084. " }\n",
  32085. " }\n",
  32086. " };\n",
  32087. "}\n",
  32088. "\n",
  32089. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  32090. "mpl.findpos = function(e) {\n",
  32091. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  32092. " var targ;\n",
  32093. " if (!e)\n",
  32094. " e = window.event;\n",
  32095. " if (e.target)\n",
  32096. " targ = e.target;\n",
  32097. " else if (e.srcElement)\n",
  32098. " targ = e.srcElement;\n",
  32099. " if (targ.nodeType == 3) // defeat Safari bug\n",
  32100. " targ = targ.parentNode;\n",
  32101. "\n",
  32102. " // jQuery normalizes the pageX and pageY\n",
  32103. " // pageX,Y are the mouse positions relative to the document\n",
  32104. " // offset() returns the position of the element relative to the document\n",
  32105. " var x = e.pageX - $(targ).offset().left;\n",
  32106. " var y = e.pageY - $(targ).offset().top;\n",
  32107. "\n",
  32108. " return {\"x\": x, \"y\": y};\n",
  32109. "};\n",
  32110. "\n",
  32111. "/*\n",
  32112. " * return a copy of an object with only non-object keys\n",
  32113. " * we need this to avoid circular references\n",
  32114. " * http://stackoverflow.com/a/24161582/3208463\n",
  32115. " */\n",
  32116. "function simpleKeys (original) {\n",
  32117. " return Object.keys(original).reduce(function (obj, key) {\n",
  32118. " if (typeof original[key] !== 'object')\n",
  32119. " obj[key] = original[key]\n",
  32120. " return obj;\n",
  32121. " }, {});\n",
  32122. "}\n",
  32123. "\n",
  32124. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  32125. " var canvas_pos = mpl.findpos(event)\n",
  32126. "\n",
  32127. " if (name === 'button_press')\n",
  32128. " {\n",
  32129. " this.canvas.focus();\n",
  32130. " this.canvas_div.focus();\n",
  32131. " }\n",
  32132. "\n",
  32133. " var x = canvas_pos.x * mpl.ratio;\n",
  32134. " var y = canvas_pos.y * mpl.ratio;\n",
  32135. "\n",
  32136. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  32137. " step: event.step,\n",
  32138. " guiEvent: simpleKeys(event)});\n",
  32139. "\n",
  32140. " /* This prevents the web browser from automatically changing to\n",
  32141. " * the text insertion cursor when the button is pressed. We want\n",
  32142. " * to control all of the cursor setting manually through the\n",
  32143. " * 'cursor' event from matplotlib */\n",
  32144. " event.preventDefault();\n",
  32145. " return false;\n",
  32146. "}\n",
  32147. "\n",
  32148. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  32149. " // Handle any extra behaviour associated with a key event\n",
  32150. "}\n",
  32151. "\n",
  32152. "mpl.figure.prototype.key_event = function(event, name) {\n",
  32153. "\n",
  32154. " // Prevent repeat events\n",
  32155. " if (name == 'key_press')\n",
  32156. " {\n",
  32157. " if (event.which === this._key)\n",
  32158. " return;\n",
  32159. " else\n",
  32160. " this._key = event.which;\n",
  32161. " }\n",
  32162. " if (name == 'key_release')\n",
  32163. " this._key = null;\n",
  32164. "\n",
  32165. " var value = '';\n",
  32166. " if (event.ctrlKey && event.which != 17)\n",
  32167. " value += \"ctrl+\";\n",
  32168. " if (event.altKey && event.which != 18)\n",
  32169. " value += \"alt+\";\n",
  32170. " if (event.shiftKey && event.which != 16)\n",
  32171. " value += \"shift+\";\n",
  32172. "\n",
  32173. " value += 'k';\n",
  32174. " value += event.which.toString();\n",
  32175. "\n",
  32176. " this._key_event_extra(event, name);\n",
  32177. "\n",
  32178. " this.send_message(name, {key: value,\n",
  32179. " guiEvent: simpleKeys(event)});\n",
  32180. " return false;\n",
  32181. "}\n",
  32182. "\n",
  32183. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  32184. " if (name == 'download') {\n",
  32185. " this.handle_save(this, null);\n",
  32186. " } else {\n",
  32187. " this.send_message(\"toolbar_button\", {name: name});\n",
  32188. " }\n",
  32189. "};\n",
  32190. "\n",
  32191. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  32192. " this.message.textContent = tooltip;\n",
  32193. "};\n",
  32194. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  32195. "\n",
  32196. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  32197. "\n",
  32198. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  32199. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  32200. " // object with the appropriate methods. Currently this is a non binary\n",
  32201. " // socket, so there is still some room for performance tuning.\n",
  32202. " var ws = {};\n",
  32203. "\n",
  32204. " ws.close = function() {\n",
  32205. " comm.close()\n",
  32206. " };\n",
  32207. " ws.send = function(m) {\n",
  32208. " //console.log('sending', m);\n",
  32209. " comm.send(m);\n",
  32210. " };\n",
  32211. " // Register the callback with on_msg.\n",
  32212. " comm.on_msg(function(msg) {\n",
  32213. " //console.log('receiving', msg['content']['data'], msg);\n",
  32214. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  32215. " ws.onmessage(msg['content']['data'])\n",
  32216. " });\n",
  32217. " return ws;\n",
  32218. "}\n",
  32219. "\n",
  32220. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  32221. " // This is the function which gets called when the mpl process\n",
  32222. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  32223. "\n",
  32224. " var id = msg.content.data.id;\n",
  32225. " // Get hold of the div created by the display call when the Comm\n",
  32226. " // socket was opened in Python.\n",
  32227. " var element = $(\"#\" + id);\n",
  32228. " var ws_proxy = comm_websocket_adapter(comm)\n",
  32229. "\n",
  32230. " function ondownload(figure, format) {\n",
  32231. " window.open(figure.imageObj.src);\n",
  32232. " }\n",
  32233. "\n",
  32234. " var fig = new mpl.figure(id, ws_proxy,\n",
  32235. " ondownload,\n",
  32236. " element.get(0));\n",
  32237. "\n",
  32238. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  32239. " // web socket which is closed, not our websocket->open comm proxy.\n",
  32240. " ws_proxy.onopen();\n",
  32241. "\n",
  32242. " fig.parent_element = element.get(0);\n",
  32243. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  32244. " if (!fig.cell_info) {\n",
  32245. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  32246. " return;\n",
  32247. " }\n",
  32248. "\n",
  32249. " var output_index = fig.cell_info[2]\n",
  32250. " var cell = fig.cell_info[0];\n",
  32251. "\n",
  32252. "};\n",
  32253. "\n",
  32254. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  32255. " var width = fig.canvas.width/mpl.ratio\n",
  32256. " fig.root.unbind('remove')\n",
  32257. "\n",
  32258. " // Update the output cell to use the data from the current canvas.\n",
  32259. " fig.push_to_output();\n",
  32260. " var dataURL = fig.canvas.toDataURL();\n",
  32261. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  32262. " // the notebook keyboard shortcuts fail.\n",
  32263. " IPython.keyboard_manager.enable()\n",
  32264. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  32265. " fig.close_ws(fig, msg);\n",
  32266. "}\n",
  32267. "\n",
  32268. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  32269. " fig.send_message('closing', msg);\n",
  32270. " // fig.ws.close()\n",
  32271. "}\n",
  32272. "\n",
  32273. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  32274. " // Turn the data on the canvas into data in the output cell.\n",
  32275. " var width = this.canvas.width/mpl.ratio\n",
  32276. " var dataURL = this.canvas.toDataURL();\n",
  32277. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  32278. "}\n",
  32279. "\n",
  32280. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  32281. " // Tell IPython that the notebook contents must change.\n",
  32282. " IPython.notebook.set_dirty(true);\n",
  32283. " this.send_message(\"ack\", {});\n",
  32284. " var fig = this;\n",
  32285. " // Wait a second, then push the new image to the DOM so\n",
  32286. " // that it is saved nicely (might be nice to debounce this).\n",
  32287. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  32288. "}\n",
  32289. "\n",
  32290. "mpl.figure.prototype._init_toolbar = function() {\n",
  32291. " var fig = this;\n",
  32292. "\n",
  32293. " var nav_element = $('<div/>')\n",
  32294. " nav_element.attr('style', 'width: 100%');\n",
  32295. " this.root.append(nav_element);\n",
  32296. "\n",
  32297. " // Define a callback function for later on.\n",
  32298. " function toolbar_event(event) {\n",
  32299. " return fig.toolbar_button_onclick(event['data']);\n",
  32300. " }\n",
  32301. " function toolbar_mouse_event(event) {\n",
  32302. " return fig.toolbar_button_onmouseover(event['data']);\n",
  32303. " }\n",
  32304. "\n",
  32305. " for(var toolbar_ind in mpl.toolbar_items){\n",
  32306. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  32307. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  32308. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  32309. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  32310. "\n",
  32311. " if (!name) { continue; };\n",
  32312. "\n",
  32313. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  32314. " button.click(method_name, toolbar_event);\n",
  32315. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  32316. " nav_element.append(button);\n",
  32317. " }\n",
  32318. "\n",
  32319. " // Add the status bar.\n",
  32320. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  32321. " nav_element.append(status_bar);\n",
  32322. " this.message = status_bar[0];\n",
  32323. "\n",
  32324. " // Add the close button to the window.\n",
  32325. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  32326. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  32327. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  32328. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  32329. " buttongrp.append(button);\n",
  32330. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  32331. " titlebar.prepend(buttongrp);\n",
  32332. "}\n",
  32333. "\n",
  32334. "mpl.figure.prototype._root_extra_style = function(el){\n",
  32335. " var fig = this\n",
  32336. " el.on(\"remove\", function(){\n",
  32337. "\tfig.close_ws(fig, {});\n",
  32338. " });\n",
  32339. "}\n",
  32340. "\n",
  32341. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  32342. " // this is important to make the div 'focusable\n",
  32343. " el.attr('tabindex', 0)\n",
  32344. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  32345. " // off when our div gets focus\n",
  32346. "\n",
  32347. " // location in version 3\n",
  32348. " if (IPython.notebook.keyboard_manager) {\n",
  32349. " IPython.notebook.keyboard_manager.register_events(el);\n",
  32350. " }\n",
  32351. " else {\n",
  32352. " // location in version 2\n",
  32353. " IPython.keyboard_manager.register_events(el);\n",
  32354. " }\n",
  32355. "\n",
  32356. "}\n",
  32357. "\n",
  32358. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  32359. " var manager = IPython.notebook.keyboard_manager;\n",
  32360. " if (!manager)\n",
  32361. " manager = IPython.keyboard_manager;\n",
  32362. "\n",
  32363. " // Check for shift+enter\n",
  32364. " if (event.shiftKey && event.which == 13) {\n",
  32365. " this.canvas_div.blur();\n",
  32366. " event.shiftKey = false;\n",
  32367. " // Send a \"J\" for go to next cell\n",
  32368. " event.which = 74;\n",
  32369. " event.keyCode = 74;\n",
  32370. " manager.command_mode();\n",
  32371. " manager.handle_keydown(event);\n",
  32372. " }\n",
  32373. "}\n",
  32374. "\n",
  32375. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  32376. " fig.ondownload(fig, null);\n",
  32377. "}\n",
  32378. "\n",
  32379. "\n",
  32380. "mpl.find_output_cell = function(html_output) {\n",
  32381. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  32382. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  32383. " // IPython event is triggered only after the cells have been serialised, which for\n",
  32384. " // our purposes (turning an active figure into a static one), is too late.\n",
  32385. " var cells = IPython.notebook.get_cells();\n",
  32386. " var ncells = cells.length;\n",
  32387. " for (var i=0; i<ncells; i++) {\n",
  32388. " var cell = cells[i];\n",
  32389. " if (cell.cell_type === 'code'){\n",
  32390. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  32391. " var data = cell.output_area.outputs[j];\n",
  32392. " if (data.data) {\n",
  32393. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  32394. " data = data.data;\n",
  32395. " }\n",
  32396. " if (data['text/html'] == html_output) {\n",
  32397. " return [cell, data, j];\n",
  32398. " }\n",
  32399. " }\n",
  32400. " }\n",
  32401. " }\n",
  32402. "}\n",
  32403. "\n",
  32404. "// Register the function which deals with the matplotlib target/channel.\n",
  32405. "// The kernel may be null if the page has been refreshed.\n",
  32406. "if (IPython.notebook.kernel != null) {\n",
  32407. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  32408. "}\n"
  32409. ],
  32410. "text/plain": [
  32411. "<IPython.core.display.Javascript object>"
  32412. ]
  32413. },
  32414. "metadata": {},
  32415. "output_type": "display_data"
  32416. },
  32417. {
  32418. "data": {
  32419. "text/html": [
  32420. "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA2AAAAJACAYAAADrSQUmAAAgAElEQVR4nO3db6ydBWHH8V+hm4gBQdwYy8hKYEtYTEymyQImszIT30B0mck0MatjvtgSmJi5LDNbvJAYFOpqojXOIBsLy15gom9kW9wMRDBjyHTCFB3ObhX8Q4sw2vHH6t2L56k9XM657e09Lfd3z+eTfBP6POfcnvvkavvrPefcBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACYo19IcnOSR5I8k2RPkg8lOfsFfEwAAACbzoVJvpdkOcmnk7w/yefGXz+Y5JwX7qEBAABsLv+YYWxdveL4X4zHP3bSHxEAAMAmdGGGkfWtJKesOHdGkgNJDiZ5yUl+XAAAAJvOOzIMsL+ccf7wd8d+46Q9IgAAgE3qxgwD649mnP/IeP4PjvPjfyvJ/iT3SZJU2v4Mf54BwLp9PMPAeseM8+8bz//pUT7OrD+0Dp2SU5fPyFmSJFV2Sk5dzjDCAGDdTvQAO3hGzlp+/ZY3S5JU2Rk5a3n8Mw0A1u1EPwXxPgNMktScAQbAPJ3oN+EwwCRJ1RlgAMzTiX4begNMklSdAQbAvJ3IH8RsgEmSqjPAAJi3C5N8L8PY+nSS65N8bvz115Ocs46PbYBJkqozwAA4Ec5P8ldJvpPk2ST/neRDSc5e58c1wCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgADQxwCRJ1RlgAIvjzUk+nOTzSf43yXKSW49yn0uT3J7ksSRPJflKkmuSnLrKfS5PckeSJ5IcSHJPkh3reNyTDDBJUnUGGMDi+HKG0fVkkq/l6APsjUkOZRhRn0hyY5IHx/vdNuM+V43n9yXZnWRXkr3jsZ3r/gwMMElSeQYYwOJ4XZJfSrIlyfasPsDOTPL9JM8kefXE8dOSfGG871tW3GdbkqeT7B//+7Czkzw03ueS43/4SQwwSVJ5BhjAYtqe1QfYleP5W6acu2w8d+eK49eNx69d48dbCwNMklSdAQawmLZn9QF263j+rVPObU1yMMkPk7xo4vhdmf1drvPGc3uP7+H+hAEmSarOAANYTNuz+gC7dzz/qhnnHxjPXzxx7NHx2Dkz7nNgPH/6MTy++2Z00ACTJDVngAEspu1ZfYB9Yzx/0Yzzd+f53+16djy2dcZ9Hh7Pn3cMj88AkyRtygwwgMW0PRt7gM3iKYiSpOoMMIDFtD0b+ymIsxhgkqTqDDCAxbQ93oRDkqSTngEGsJi2x9vQS5J00jPAABbT9hz9BzE/mrX9IOYL4gcxS5K0agYYwOJ4U5K/HvuHDIPomxPHdk65/aEMr926KckNSR4c73dbki1Tfo+rx/P7kuxOsivD0w6Xp3z842GASZKqM8AAFsdShiE0qz1T7vOaJLcn+UGSp5Lcn+RdSU5d5fe5IsPTE5/M8Fqxe5PsmMPjTwwwSVJ5BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhgATQwwSVJ1BhjAYjgnyTuSfCrJQ0meSvJEkruS/F6SU2bc79Iktyd5bLzPV5Jck+TUVX6vy5PcMX78A0nuSbJjvZ/AyACTJFVngAEsht9PspzkkSR/m+T6JDcneXw8/skkW1bc541JDmUYUZ9IcmOSB8fb3zbj97lqPL8vye4ku5LsHY/tnMPnYYBJkqozwAAWw2VJrsjzv9P1c0n+J8NA+q2J42cm+X6SZ5K8euL4aUm+MN7+LSs+1rYkTyfZP/73YWdn+K7bcpJLjv9TSGKASZLKM8AAeE+GcfThiWNXjsdumXL7y8Zzd644ft14/Nop91nt462FASZJqs4AA+CPM4yjXRPHbh2PvXXK7bcmOZjkh0leNHH8rsz+Ltd547m963ysBpgkqToDDGCxbU1yf4Zx9IaJ4/eOx141434PjOcvnjj26HjsnBn3OTCeP/0YHtd9MzpogEmSmjPAABbbzgyj6DMrjn9jPH7RjPvdned/t+vZ8djWGfd5eDx/3jE8LgNMkrQpM8AAFtcfZhhEX0vyshXnXugBNounIEqSqjPAABbT4beL/48M74S40gv9FMRZDDBJUnUGGMDiuSbDELo/yc/OuI034ZAk6QRkgAEslj/JMIS+lOTlq9zO29BLknQCMsAAFsefZxhBX8zzX/O10pkZnlK4lh/EfEH8IGZJklbNAANYDDsyDKBDGX7e19KU3r7iPm8ab38gyU1Jbkjy4PhxbkuyZcrvc/V4fl+S3ePvtXc8tnMOn4cBJkmqzgADWAxLGUbQat0x5X6vSXJ7kh8keSrD68beleTUVX6vKzI8PfHJDK8VuzfDAJwHA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBkATA0ySVJ0BBrA4PpDkn5PsTfJUkseSfCnJe5OcM+M+lya5fbztU0m+kuSaJKeu8vtcnuSOJE8kOZDkniQ71v3oBwaYJKk6AwxgcTyb5F+S3Jzk/Uk+nOTeJMtJHk5y/orbvzHJoQwj6hNJbkzy4Hj722b8HleN5/cl2Z1kV4bBt5xk5xw+BwNMklSdAQawOE6bcfx9GQbSRyeOnZnk+0meSfLqFR/jC+Pt37Li42xL8nSS/eN/H3Z2kofG+1xyXI/8CANMklSdAQbAKzOMo89OHLtyPHbLlNtfNp67c8Xx68bj1065z2ofby0MMElSdQYYAH+WYRx9cOLYreOxt065/dYkB5P8MMmLJo7fldnf5TpvPLd3nY/VAJMkVWeAASyedydZyvD6rM9nGEb/nuRnJm5z+LVhr5rxMR4Yz188cezR8disN/Q4MJ4//Rge430zOmiASZKaM8AAFs93Mwyhw/19knNX3OYb47mLZnyMu/P873Y9Ox7bOuM+D4/nzzuGx2iASZI2ZQYYwOI6N8lvJvl6kkeS/OrEuRd6gM3iKYiSpOoMMAB+McO7HT4wceyFfgriLAaYJKk6AwyAZPiBzMtJXj7+2ptwSJJ0AjLAAEiS72UYSGePv/Y29JIknYAMMIDF8MtJXjrl+Ck58oOY7544fmaGpxSu5QcxXxA/iFmSpFUzwAAWwzVJnsrww5Y/nuT6JDcn+WaGYfSdJL+y4j5vSnIow2u3bkpyQ5IHx9vflmTLlN/n6vH8viS7M7zV/d7x2M45fB4GmCSpOgMMYDG8IslHknw5wzg6lOSJDG+2sZTkZTPu95oktyf5QYYBd3+SdyU5dZXf64oMT098MsNrxe5NsmO9n8DIAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJMkVWeAAdDEAJP0nH70nYvm1gv9uWgxMsAAaGKASfpJ8xxfBphOVgYYAE0MMEnLr98y//FlgOlkZYAB0MQAk3RCxpcBppOVAQZAEwNM0gkbYEaYTkYGGABNDDBpwTuR48sA08nIAAOgiQEmLXgneoAZYTrRGWAANDHApAXvZAwwI0wnMgMMgCYGmLTgGWBqzwADoIkBJskIU3UGGABNDDBJBpiqM8AAaGKASTppA8wI04nIAAOgiQEmafn1W7wbonozwABoYoBJWn79FgNMvRlgADQxwCR5+qGqM8AAaGKASTLAVJ0BBkATA0zSTzK+1JgBBkATA0zSczLA1JYBBkATA0zS8zK+1JQBBkATA0zS1NY7tIwvnawMMACaGGCSpjZrYPkOlzZaBhgATQwwScedAaaNkAEGQBMDTJJUnQEGQBMDTJJUnQEGQBMDTJJUnQEGQBMDTJJUnQEGQBMDTJJUnQEGQBMDTJJUnQEGQBMDTJJUnQEGQBMDTJJUnQEGQBMDTJJUnQEGQBMDTJJUnQEGsNjelmR57B0zbnN5kjuSPJHkQJJ7kuw4ysfdkeRfx9s/Md7/8nU/WgNMklSeAQawuM5P8niSJzN7gF01ntuXZHeSXUn2jsd2zvi4O8fze8fb706yfzx21TofswEmSarOAANYTFuS/FOSbya5MdMH2LYkT2cYT9smjp+d5KHxPpesuM+l4/GHxttNfqz948fbluNngEmSqjPAABbTO5P8OMmvJ1nK9AF23Xj82in3v3I8d8uK438zHv/dKfdZ7eMdKwNMklSdAQaweC5O8lSGpwcmswfYXZn+Xa4kOS9HnmY46dvj8fOm3OeS8dznj+dBjwwwSVJ1BhjAYtma5ItJvp7kxeOxpUwfYI+Ox8+Z8bEOjOdPH3/9kvHXT864/cvH8987hsd534wOGmCSpOYMMIDFcl2SH+W539VayvQB9ux4fOuMj/Vwnvvdrp8ff/3tGbf/qfH8M8fwOA0wSdKmzAADWBy/luRQkhtWHF/Kxhtgs3gKoiSpOgMMYDFszfC0w68medGKc0vZeE9BnMUAkyRVZ4ABLIazcuQHLh+tD4338SYckiTNOQMMYDG8OMlNM/q3HBlGNyX57fE+3oZekqQ5Z4ABsJTpT0G8IH4QsyRJc80AA2Ap0wdYklw9ntuXZHeGnx22dzy2c8bH+2COPD1x13i/feOxq9b5WA0wSVJ1BhgAS5k9wJLkiiR3ZnhzjYNJ7k2y4ygf8+3j7Q6O97szyeXrf6gGmCSpOwMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMgCYGmCSpOgMMYHHsSbI8o+/OuM+lSW5P8liSp5J8Jck1SU5d5fe5PMkdSZ5IciDJPUl2rPfBjwwwSVJ1BhjA4tiT5PEkS1N695TbvzHJoQwj6hNJbkzyYIbBdtuM3+Oq8fy+JLuT7Eqydzy2c92fgQEmSSrPAANYHHvGjsWZSb6f5Jkkr544flqSL2QYVG9ZcZ9tSZ5Osn/878POTvLQeJ9L1vSIn88AkyRVZ4ABLI49OfYBdmWGwXTLlHOXjefuXHH8uvH4tWv8eGthgEmSqjPAABbHniTfSfK2JO9J8s4kr8v013PdmmEwvXXKua1JDib5YZIXTRy/K7O/y3XeeG7v8T30nzDAJEnVGWAAi2NPpr8Bx38lee2K2947nnvVjI/1wHj+4oljj47HzplxnwPj+dOP4bHeN6ODBpgkqTkDDGBxvDfD0wfPzTCCXpHkY0l+nOT/krxy4rbfyDCWLprxse7O87/b9ex4bOuM+zw8nj/vGB6rASZJ2pQZYADszDCMPjVx7IUeYLN4CqIkqToDDICLMgyj/RPHXuinIM5igEmSqjPAAHhphmH09MQxb8IhSdIJyAAD4A0ZxtFXJ455G3pJkk5ABhjAYrg4yUumHN+W5D8zjKP3TBw/M8NTCtfyg5gviB/ELEnSqhlgAIthKcmTST6T5KNJPpDkk0meyjCMPpPkp1fc501JDmV47dZNSW5I8uB4+9uSbJny+1w9nt+XZHeSXRmedric4c0+1ssAkyRVZ4ABLIbXJvm7DAPq8Qyv33o0yWeT/E6mj6kkeU2S25P8IMNYuz/JuzL9hzcfdkWGpyc+meG1Yvcm2bHuz2BggEmSqjPAAGhigEmSqjPAAGiy/5ScunxGzpIkqbJTcurKH/0CABvWtzK8Lu1ghn891Hw66Jq6pgW5pq7pRu9Yr+f+DH+eAUCFw3+AMT+u6fy5pvPnms6fazpfricAm5I/4ObPNZ0/13T+XNP5c03ny/UEYFPyB9z8uabz55rOn2s6f67pfLmeAGxK/oCbP9d0/lzT+XNN5881nS/XE4BNyR9w8+eazp9rOn+u6fy5pvPlegKwKfkDbv5c0/lzTefPNZ0/13S+XE8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACABfcLSW5O8kiSZ5LsSfKhJGe/gI9po3hzkg8n+XyS/02ynOTWo9zn0iS3J3ksyVNJvpLkmiSnrnKfy5PckeSJJAeS3JNkxzoe90Z1TpJ3JPlUkocyXJ8nktyV5PeSnDLjfq7p6j6Q5J+T7M1wfR5L8qUk781wzadxTdfmbRn+97+c4Wt4muO5PjuS/Ot4+yfG+1++7ke7Me3JkWu4su/OuI+vUwA2nQuTfC/DH4CfTvL+JJ8bf/1gZv/lbVF8OcO1eDLJ13L0AfbGJIcy/KH/iSQ3ZriOy0lum3Gfq8bz+5LsTrIrw1+kl5PsXPdnsLH8fobP65Ekf5vk+gzj//Hx+CeTbFlxH9f06J5N8i8ZruX7M/yjwb0ZPt+Hk5y/4vau6dqcn+Fr9MnMHmDHc312juf3jrffnWT/eOyq+T38DWNPhuu4NKV3T7m9r1MANqV/zPAH09Urjv/FePxjJ/0RbSyvS/JLGUbB9qw+wM5M8v0M30V89cTx05J8YbzvW1bcZ1uSpzP8pWvbxPGzM3yHaDnJJcf/8Decy5Jcked/p+vnkvxPhs/3tyaOu6bH5rQZx9+X4fP96MQx13RttiT5pyTfzDAApg2wbVn79bl0PP5Qnvtsg23jx3l6xcfaDPaMHQtfpwBsShdm+APpW3n+X4jPyPCvjgeTvOQkP66NantWH2BXjudvmXLusvHcnSuOXzcev3aNH28zek+Gz/fDE8dc0/V5ZYbP97MTx1zTtXlnkh8n+fUM36mZNsCO5/r8zXj8d6fcZ7WP12xPjn2A+ToFYFN6R4Y/kP5yxvnD3x37jZP2iDa27Vl9gN06nn/rlHNbM4zZHyZ50cTxuzL7X2XPy5GnJy2CP87w+e6aOOaars+fZfh8PzhxzDU9dhdneN3R4a/JpUwfYMdzfb49Hj9vyn0uGc99/nge9Aa2J8l3Mrye7j0Zxu3rMv31XL5OAdiUDj+d5o9mnP/IeP4PTtoj2ti2Z/UBdvg1N6+acf6B8fzFE8ceHY/Neq3dgfH86Wt8rG22Jrk/w+f6honjrunavDvDSNiV4S/vy0n+PcnPTNzGNT02W5N8McnXk7x4PLaU6QNsrdfnJTny2tJpXj6e/95xPO6NbE+mvwHHfyV57Yrb+joFYFP6eFZ/R6/Drx/505P2iDa27Vl9gH1jPH/RjPN35/n/OvvseGzrjPs8nNn/Sr6ZHH4zgs+sOO6ars1389y/2P59knNX3MY1PTbXJflRnnsdljL9/zPXen1+fvz1t2fc/qfG88+s9UFvcO/N8PTBczOMoFdkeJ3xj5P8X4anzB7m6xSATckAW5vtMcBOhD/M8GBK48gAAAMoSURBVDl+LcnLVpxzTY/PuUl+M8N3bx5J8qsT51zTo/u1DO++d8OK40sxwE6Ew/8A86mJY75OAdiUPAVxbbbHUxDn7fBbRv9HhndCXMk1XZ9fzPCX+Acmjrmmq9uaYbh+Nc99fVHiKYgnykUZPt/9E8d8nQKwKXkTjrXZntUHmBeNr801GT6/+5P87IzbuKbr96UMn/PLx1+7pqs7K9NfpzStD4338SYc6/PSDJ/v0xPHfJ0CsCl5G/q12Z7VB5i3TT52f5Lhc/tSjgyDaVzT9Tv8g9YP/6wp13R1L05y04z+LUeG0U1Jfnu8j7ehX583ZPh8vzpxzNcpAJuWH8R87LZn9QF2ZoanwKzlB4dekMX7waF/nuHz+mKe/5qvlVzTo/vlDN9BWOmUHHkd590Tx13T47eU6U9BPJ7rs2g/iPniTP/HvG1J/jPDtXjPxHFfpwBsWhfmyL+QfzrJ9Uk+N/7665n9XPpF8aYkfz32Dxmuyzcnju2ccvtDGb57eFOGF/E/ON7vtiRbpvweV4/n9yXZneEtxPeOx1Z+/HY7MnxehzJ8nktTevuK+7imq7smw8+q+myGN9a5PsnNGb5OlzP83KVfWXEf1/T4LGX6AEuO7/p8MEeeFrdrvN++8dhVc3zcG8FShte8fSbJR5N8IMknM3ztLo/Hf3rFfXydArBpnZ/krzL8Re3ZJP+d4bUNZ692pwWxlNVfA7Jnyn1ek+T2JD/I8JeL+5O8K9N/2OhhV2R4Os2TGZ72eW+GsbLZLOXor6u5Y8r9XNPZXpHhDXO+nOEvnYeSPJHh813K7O8yuqZrt5TZAyw5vuvz9vF2B8f73Znk8vU/1A3ntUn+LsOAejzD67cezfAPB7+T6WMq8XUKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG8X/A9NhyaxN2bmJAAAAAElFTkSuQmCC\" width=\"432\">"
  32421. ],
  32422. "text/plain": [
  32423. "<IPython.core.display.HTML object>"
  32424. ]
  32425. },
  32426. "metadata": {},
  32427. "output_type": "display_data"
  32428. },
  32429. {
  32430. "name": "stdout",
  32431. "output_type": "stream",
  32432. "text": [
  32433. "0 1\n",
  32434. "673\n",
  32435. "(355, 309)\n",
  32436. "\n"
  32437. ]
  32438. },
  32439. {
  32440. "data": {
  32441. "application/javascript": [
  32442. "/* Put everything inside the global mpl namespace */\n",
  32443. "window.mpl = {};\n",
  32444. "\n",
  32445. "\n",
  32446. "mpl.get_websocket_type = function() {\n",
  32447. " if (typeof(WebSocket) !== 'undefined') {\n",
  32448. " return WebSocket;\n",
  32449. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  32450. " return MozWebSocket;\n",
  32451. " } else {\n",
  32452. " alert('Your browser does not have WebSocket support.' +\n",
  32453. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  32454. " 'Firefox 4 and 5 are also supported but you ' +\n",
  32455. " 'have to enable WebSockets in about:config.');\n",
  32456. " };\n",
  32457. "}\n",
  32458. "\n",
  32459. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  32460. " this.id = figure_id;\n",
  32461. "\n",
  32462. " this.ws = websocket;\n",
  32463. "\n",
  32464. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  32465. "\n",
  32466. " if (!this.supports_binary) {\n",
  32467. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  32468. " if (warnings) {\n",
  32469. " warnings.style.display = 'block';\n",
  32470. " warnings.textContent = (\n",
  32471. " \"This browser does not support binary websocket messages. \" +\n",
  32472. " \"Performance may be slow.\");\n",
  32473. " }\n",
  32474. " }\n",
  32475. "\n",
  32476. " this.imageObj = new Image();\n",
  32477. "\n",
  32478. " this.context = undefined;\n",
  32479. " this.message = undefined;\n",
  32480. " this.canvas = undefined;\n",
  32481. " this.rubberband_canvas = undefined;\n",
  32482. " this.rubberband_context = undefined;\n",
  32483. " this.format_dropdown = undefined;\n",
  32484. "\n",
  32485. " this.image_mode = 'full';\n",
  32486. "\n",
  32487. " this.root = $('<div/>');\n",
  32488. " this._root_extra_style(this.root)\n",
  32489. " this.root.attr('style', 'display: inline-block');\n",
  32490. "\n",
  32491. " $(parent_element).append(this.root);\n",
  32492. "\n",
  32493. " this._init_header(this);\n",
  32494. " this._init_canvas(this);\n",
  32495. " this._init_toolbar(this);\n",
  32496. "\n",
  32497. " var fig = this;\n",
  32498. "\n",
  32499. " this.waiting = false;\n",
  32500. "\n",
  32501. " this.ws.onopen = function () {\n",
  32502. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  32503. " fig.send_message(\"send_image_mode\", {});\n",
  32504. " if (mpl.ratio != 1) {\n",
  32505. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  32506. " }\n",
  32507. " fig.send_message(\"refresh\", {});\n",
  32508. " }\n",
  32509. "\n",
  32510. " this.imageObj.onload = function() {\n",
  32511. " if (fig.image_mode == 'full') {\n",
  32512. " // Full images could contain transparency (where diff images\n",
  32513. " // almost always do), so we need to clear the canvas so that\n",
  32514. " // there is no ghosting.\n",
  32515. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  32516. " }\n",
  32517. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  32518. " };\n",
  32519. "\n",
  32520. " this.imageObj.onunload = function() {\n",
  32521. " fig.ws.close();\n",
  32522. " }\n",
  32523. "\n",
  32524. " this.ws.onmessage = this._make_on_message_function(this);\n",
  32525. "\n",
  32526. " this.ondownload = ondownload;\n",
  32527. "}\n",
  32528. "\n",
  32529. "mpl.figure.prototype._init_header = function() {\n",
  32530. " var titlebar = $(\n",
  32531. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  32532. " 'ui-helper-clearfix\"/>');\n",
  32533. " var titletext = $(\n",
  32534. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  32535. " 'text-align: center; padding: 3px;\"/>');\n",
  32536. " titlebar.append(titletext)\n",
  32537. " this.root.append(titlebar);\n",
  32538. " this.header = titletext[0];\n",
  32539. "}\n",
  32540. "\n",
  32541. "\n",
  32542. "\n",
  32543. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  32544. "\n",
  32545. "}\n",
  32546. "\n",
  32547. "\n",
  32548. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  32549. "\n",
  32550. "}\n",
  32551. "\n",
  32552. "mpl.figure.prototype._init_canvas = function() {\n",
  32553. " var fig = this;\n",
  32554. "\n",
  32555. " var canvas_div = $('<div/>');\n",
  32556. "\n",
  32557. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  32558. "\n",
  32559. " function canvas_keyboard_event(event) {\n",
  32560. " return fig.key_event(event, event['data']);\n",
  32561. " }\n",
  32562. "\n",
  32563. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  32564. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  32565. " this.canvas_div = canvas_div\n",
  32566. " this._canvas_extra_style(canvas_div)\n",
  32567. " this.root.append(canvas_div);\n",
  32568. "\n",
  32569. " var canvas = $('<canvas/>');\n",
  32570. " canvas.addClass('mpl-canvas');\n",
  32571. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  32572. "\n",
  32573. " this.canvas = canvas[0];\n",
  32574. " this.context = canvas[0].getContext(\"2d\");\n",
  32575. "\n",
  32576. " var backingStore = this.context.backingStorePixelRatio ||\n",
  32577. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  32578. "\tthis.context.mozBackingStorePixelRatio ||\n",
  32579. "\tthis.context.msBackingStorePixelRatio ||\n",
  32580. "\tthis.context.oBackingStorePixelRatio ||\n",
  32581. "\tthis.context.backingStorePixelRatio || 1;\n",
  32582. "\n",
  32583. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  32584. "\n",
  32585. " var rubberband = $('<canvas/>');\n",
  32586. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  32587. "\n",
  32588. " var pass_mouse_events = true;\n",
  32589. "\n",
  32590. " canvas_div.resizable({\n",
  32591. " start: function(event, ui) {\n",
  32592. " pass_mouse_events = false;\n",
  32593. " },\n",
  32594. " resize: function(event, ui) {\n",
  32595. " fig.request_resize(ui.size.width, ui.size.height);\n",
  32596. " },\n",
  32597. " stop: function(event, ui) {\n",
  32598. " pass_mouse_events = true;\n",
  32599. " fig.request_resize(ui.size.width, ui.size.height);\n",
  32600. " },\n",
  32601. " });\n",
  32602. "\n",
  32603. " function mouse_event_fn(event) {\n",
  32604. " if (pass_mouse_events)\n",
  32605. " return fig.mouse_event(event, event['data']);\n",
  32606. " }\n",
  32607. "\n",
  32608. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  32609. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  32610. " // Throttle sequential mouse events to 1 every 20ms.\n",
  32611. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  32612. "\n",
  32613. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  32614. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  32615. "\n",
  32616. " canvas_div.on(\"wheel\", function (event) {\n",
  32617. " event = event.originalEvent;\n",
  32618. " event['data'] = 'scroll'\n",
  32619. " if (event.deltaY < 0) {\n",
  32620. " event.step = 1;\n",
  32621. " } else {\n",
  32622. " event.step = -1;\n",
  32623. " }\n",
  32624. " mouse_event_fn(event);\n",
  32625. " });\n",
  32626. "\n",
  32627. " canvas_div.append(canvas);\n",
  32628. " canvas_div.append(rubberband);\n",
  32629. "\n",
  32630. " this.rubberband = rubberband;\n",
  32631. " this.rubberband_canvas = rubberband[0];\n",
  32632. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  32633. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  32634. "\n",
  32635. " this._resize_canvas = function(width, height) {\n",
  32636. " // Keep the size of the canvas, canvas container, and rubber band\n",
  32637. " // canvas in synch.\n",
  32638. " canvas_div.css('width', width)\n",
  32639. " canvas_div.css('height', height)\n",
  32640. "\n",
  32641. " canvas.attr('width', width * mpl.ratio);\n",
  32642. " canvas.attr('height', height * mpl.ratio);\n",
  32643. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  32644. "\n",
  32645. " rubberband.attr('width', width);\n",
  32646. " rubberband.attr('height', height);\n",
  32647. " }\n",
  32648. "\n",
  32649. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  32650. " // upon first draw.\n",
  32651. " this._resize_canvas(600, 600);\n",
  32652. "\n",
  32653. " // Disable right mouse context menu.\n",
  32654. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  32655. " return false;\n",
  32656. " });\n",
  32657. "\n",
  32658. " function set_focus () {\n",
  32659. " canvas.focus();\n",
  32660. " canvas_div.focus();\n",
  32661. " }\n",
  32662. "\n",
  32663. " window.setTimeout(set_focus, 100);\n",
  32664. "}\n",
  32665. "\n",
  32666. "mpl.figure.prototype._init_toolbar = function() {\n",
  32667. " var fig = this;\n",
  32668. "\n",
  32669. " var nav_element = $('<div/>')\n",
  32670. " nav_element.attr('style', 'width: 100%');\n",
  32671. " this.root.append(nav_element);\n",
  32672. "\n",
  32673. " // Define a callback function for later on.\n",
  32674. " function toolbar_event(event) {\n",
  32675. " return fig.toolbar_button_onclick(event['data']);\n",
  32676. " }\n",
  32677. " function toolbar_mouse_event(event) {\n",
  32678. " return fig.toolbar_button_onmouseover(event['data']);\n",
  32679. " }\n",
  32680. "\n",
  32681. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  32682. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  32683. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  32684. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  32685. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  32686. "\n",
  32687. " if (!name) {\n",
  32688. " // put a spacer in here.\n",
  32689. " continue;\n",
  32690. " }\n",
  32691. " var button = $('<button/>');\n",
  32692. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  32693. " 'ui-button-icon-only');\n",
  32694. " button.attr('role', 'button');\n",
  32695. " button.attr('aria-disabled', 'false');\n",
  32696. " button.click(method_name, toolbar_event);\n",
  32697. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  32698. "\n",
  32699. " var icon_img = $('<span/>');\n",
  32700. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  32701. " icon_img.addClass(image);\n",
  32702. " icon_img.addClass('ui-corner-all');\n",
  32703. "\n",
  32704. " var tooltip_span = $('<span/>');\n",
  32705. " tooltip_span.addClass('ui-button-text');\n",
  32706. " tooltip_span.html(tooltip);\n",
  32707. "\n",
  32708. " button.append(icon_img);\n",
  32709. " button.append(tooltip_span);\n",
  32710. "\n",
  32711. " nav_element.append(button);\n",
  32712. " }\n",
  32713. "\n",
  32714. " var fmt_picker_span = $('<span/>');\n",
  32715. "\n",
  32716. " var fmt_picker = $('<select/>');\n",
  32717. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  32718. " fmt_picker_span.append(fmt_picker);\n",
  32719. " nav_element.append(fmt_picker_span);\n",
  32720. " this.format_dropdown = fmt_picker[0];\n",
  32721. "\n",
  32722. " for (var ind in mpl.extensions) {\n",
  32723. " var fmt = mpl.extensions[ind];\n",
  32724. " var option = $(\n",
  32725. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  32726. " fmt_picker.append(option)\n",
  32727. " }\n",
  32728. "\n",
  32729. " // Add hover states to the ui-buttons\n",
  32730. " $( \".ui-button\" ).hover(\n",
  32731. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  32732. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  32733. " );\n",
  32734. "\n",
  32735. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  32736. " nav_element.append(status_bar);\n",
  32737. " this.message = status_bar[0];\n",
  32738. "}\n",
  32739. "\n",
  32740. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  32741. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  32742. " // which will in turn request a refresh of the image.\n",
  32743. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  32744. "}\n",
  32745. "\n",
  32746. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  32747. " properties['type'] = type;\n",
  32748. " properties['figure_id'] = this.id;\n",
  32749. " this.ws.send(JSON.stringify(properties));\n",
  32750. "}\n",
  32751. "\n",
  32752. "mpl.figure.prototype.send_draw_message = function() {\n",
  32753. " if (!this.waiting) {\n",
  32754. " this.waiting = true;\n",
  32755. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  32756. " }\n",
  32757. "}\n",
  32758. "\n",
  32759. "\n",
  32760. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  32761. " var format_dropdown = fig.format_dropdown;\n",
  32762. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  32763. " fig.ondownload(fig, format);\n",
  32764. "}\n",
  32765. "\n",
  32766. "\n",
  32767. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  32768. " var size = msg['size'];\n",
  32769. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  32770. " fig._resize_canvas(size[0], size[1]);\n",
  32771. " fig.send_message(\"refresh\", {});\n",
  32772. " };\n",
  32773. "}\n",
  32774. "\n",
  32775. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  32776. " var x0 = msg['x0'] / mpl.ratio;\n",
  32777. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  32778. " var x1 = msg['x1'] / mpl.ratio;\n",
  32779. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  32780. " x0 = Math.floor(x0) + 0.5;\n",
  32781. " y0 = Math.floor(y0) + 0.5;\n",
  32782. " x1 = Math.floor(x1) + 0.5;\n",
  32783. " y1 = Math.floor(y1) + 0.5;\n",
  32784. " var min_x = Math.min(x0, x1);\n",
  32785. " var min_y = Math.min(y0, y1);\n",
  32786. " var width = Math.abs(x1 - x0);\n",
  32787. " var height = Math.abs(y1 - y0);\n",
  32788. "\n",
  32789. " fig.rubberband_context.clearRect(\n",
  32790. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  32791. "\n",
  32792. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  32793. "}\n",
  32794. "\n",
  32795. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  32796. " // Updates the figure title.\n",
  32797. " fig.header.textContent = msg['label'];\n",
  32798. "}\n",
  32799. "\n",
  32800. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  32801. " var cursor = msg['cursor'];\n",
  32802. " switch(cursor)\n",
  32803. " {\n",
  32804. " case 0:\n",
  32805. " cursor = 'pointer';\n",
  32806. " break;\n",
  32807. " case 1:\n",
  32808. " cursor = 'default';\n",
  32809. " break;\n",
  32810. " case 2:\n",
  32811. " cursor = 'crosshair';\n",
  32812. " break;\n",
  32813. " case 3:\n",
  32814. " cursor = 'move';\n",
  32815. " break;\n",
  32816. " }\n",
  32817. " fig.rubberband_canvas.style.cursor = cursor;\n",
  32818. "}\n",
  32819. "\n",
  32820. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  32821. " fig.message.textContent = msg['message'];\n",
  32822. "}\n",
  32823. "\n",
  32824. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  32825. " // Request the server to send over a new figure.\n",
  32826. " fig.send_draw_message();\n",
  32827. "}\n",
  32828. "\n",
  32829. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  32830. " fig.image_mode = msg['mode'];\n",
  32831. "}\n",
  32832. "\n",
  32833. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  32834. " // Called whenever the canvas gets updated.\n",
  32835. " this.send_message(\"ack\", {});\n",
  32836. "}\n",
  32837. "\n",
  32838. "// A function to construct a web socket function for onmessage handling.\n",
  32839. "// Called in the figure constructor.\n",
  32840. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  32841. " return function socket_on_message(evt) {\n",
  32842. " if (evt.data instanceof Blob) {\n",
  32843. " /* FIXME: We get \"Resource interpreted as Image but\n",
  32844. " * transferred with MIME type text/plain:\" errors on\n",
  32845. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  32846. " * to be part of the websocket stream */\n",
  32847. " evt.data.type = \"image/png\";\n",
  32848. "\n",
  32849. " /* Free the memory for the previous frames */\n",
  32850. " if (fig.imageObj.src) {\n",
  32851. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  32852. " fig.imageObj.src);\n",
  32853. " }\n",
  32854. "\n",
  32855. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  32856. " evt.data);\n",
  32857. " fig.updated_canvas_event();\n",
  32858. " fig.waiting = false;\n",
  32859. " return;\n",
  32860. " }\n",
  32861. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  32862. " fig.imageObj.src = evt.data;\n",
  32863. " fig.updated_canvas_event();\n",
  32864. " fig.waiting = false;\n",
  32865. " return;\n",
  32866. " }\n",
  32867. "\n",
  32868. " var msg = JSON.parse(evt.data);\n",
  32869. " var msg_type = msg['type'];\n",
  32870. "\n",
  32871. " // Call the \"handle_{type}\" callback, which takes\n",
  32872. " // the figure and JSON message as its only arguments.\n",
  32873. " try {\n",
  32874. " var callback = fig[\"handle_\" + msg_type];\n",
  32875. " } catch (e) {\n",
  32876. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  32877. " return;\n",
  32878. " }\n",
  32879. "\n",
  32880. " if (callback) {\n",
  32881. " try {\n",
  32882. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  32883. " callback(fig, msg);\n",
  32884. " } catch (e) {\n",
  32885. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  32886. " }\n",
  32887. " }\n",
  32888. " };\n",
  32889. "}\n",
  32890. "\n",
  32891. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  32892. "mpl.findpos = function(e) {\n",
  32893. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  32894. " var targ;\n",
  32895. " if (!e)\n",
  32896. " e = window.event;\n",
  32897. " if (e.target)\n",
  32898. " targ = e.target;\n",
  32899. " else if (e.srcElement)\n",
  32900. " targ = e.srcElement;\n",
  32901. " if (targ.nodeType == 3) // defeat Safari bug\n",
  32902. " targ = targ.parentNode;\n",
  32903. "\n",
  32904. " // jQuery normalizes the pageX and pageY\n",
  32905. " // pageX,Y are the mouse positions relative to the document\n",
  32906. " // offset() returns the position of the element relative to the document\n",
  32907. " var x = e.pageX - $(targ).offset().left;\n",
  32908. " var y = e.pageY - $(targ).offset().top;\n",
  32909. "\n",
  32910. " return {\"x\": x, \"y\": y};\n",
  32911. "};\n",
  32912. "\n",
  32913. "/*\n",
  32914. " * return a copy of an object with only non-object keys\n",
  32915. " * we need this to avoid circular references\n",
  32916. " * http://stackoverflow.com/a/24161582/3208463\n",
  32917. " */\n",
  32918. "function simpleKeys (original) {\n",
  32919. " return Object.keys(original).reduce(function (obj, key) {\n",
  32920. " if (typeof original[key] !== 'object')\n",
  32921. " obj[key] = original[key]\n",
  32922. " return obj;\n",
  32923. " }, {});\n",
  32924. "}\n",
  32925. "\n",
  32926. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  32927. " var canvas_pos = mpl.findpos(event)\n",
  32928. "\n",
  32929. " if (name === 'button_press')\n",
  32930. " {\n",
  32931. " this.canvas.focus();\n",
  32932. " this.canvas_div.focus();\n",
  32933. " }\n",
  32934. "\n",
  32935. " var x = canvas_pos.x * mpl.ratio;\n",
  32936. " var y = canvas_pos.y * mpl.ratio;\n",
  32937. "\n",
  32938. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  32939. " step: event.step,\n",
  32940. " guiEvent: simpleKeys(event)});\n",
  32941. "\n",
  32942. " /* This prevents the web browser from automatically changing to\n",
  32943. " * the text insertion cursor when the button is pressed. We want\n",
  32944. " * to control all of the cursor setting manually through the\n",
  32945. " * 'cursor' event from matplotlib */\n",
  32946. " event.preventDefault();\n",
  32947. " return false;\n",
  32948. "}\n",
  32949. "\n",
  32950. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  32951. " // Handle any extra behaviour associated with a key event\n",
  32952. "}\n",
  32953. "\n",
  32954. "mpl.figure.prototype.key_event = function(event, name) {\n",
  32955. "\n",
  32956. " // Prevent repeat events\n",
  32957. " if (name == 'key_press')\n",
  32958. " {\n",
  32959. " if (event.which === this._key)\n",
  32960. " return;\n",
  32961. " else\n",
  32962. " this._key = event.which;\n",
  32963. " }\n",
  32964. " if (name == 'key_release')\n",
  32965. " this._key = null;\n",
  32966. "\n",
  32967. " var value = '';\n",
  32968. " if (event.ctrlKey && event.which != 17)\n",
  32969. " value += \"ctrl+\";\n",
  32970. " if (event.altKey && event.which != 18)\n",
  32971. " value += \"alt+\";\n",
  32972. " if (event.shiftKey && event.which != 16)\n",
  32973. " value += \"shift+\";\n",
  32974. "\n",
  32975. " value += 'k';\n",
  32976. " value += event.which.toString();\n",
  32977. "\n",
  32978. " this._key_event_extra(event, name);\n",
  32979. "\n",
  32980. " this.send_message(name, {key: value,\n",
  32981. " guiEvent: simpleKeys(event)});\n",
  32982. " return false;\n",
  32983. "}\n",
  32984. "\n",
  32985. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  32986. " if (name == 'download') {\n",
  32987. " this.handle_save(this, null);\n",
  32988. " } else {\n",
  32989. " this.send_message(\"toolbar_button\", {name: name});\n",
  32990. " }\n",
  32991. "};\n",
  32992. "\n",
  32993. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  32994. " this.message.textContent = tooltip;\n",
  32995. "};\n",
  32996. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  32997. "\n",
  32998. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  32999. "\n",
  33000. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  33001. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  33002. " // object with the appropriate methods. Currently this is a non binary\n",
  33003. " // socket, so there is still some room for performance tuning.\n",
  33004. " var ws = {};\n",
  33005. "\n",
  33006. " ws.close = function() {\n",
  33007. " comm.close()\n",
  33008. " };\n",
  33009. " ws.send = function(m) {\n",
  33010. " //console.log('sending', m);\n",
  33011. " comm.send(m);\n",
  33012. " };\n",
  33013. " // Register the callback with on_msg.\n",
  33014. " comm.on_msg(function(msg) {\n",
  33015. " //console.log('receiving', msg['content']['data'], msg);\n",
  33016. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  33017. " ws.onmessage(msg['content']['data'])\n",
  33018. " });\n",
  33019. " return ws;\n",
  33020. "}\n",
  33021. "\n",
  33022. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  33023. " // This is the function which gets called when the mpl process\n",
  33024. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  33025. "\n",
  33026. " var id = msg.content.data.id;\n",
  33027. " // Get hold of the div created by the display call when the Comm\n",
  33028. " // socket was opened in Python.\n",
  33029. " var element = $(\"#\" + id);\n",
  33030. " var ws_proxy = comm_websocket_adapter(comm)\n",
  33031. "\n",
  33032. " function ondownload(figure, format) {\n",
  33033. " window.open(figure.imageObj.src);\n",
  33034. " }\n",
  33035. "\n",
  33036. " var fig = new mpl.figure(id, ws_proxy,\n",
  33037. " ondownload,\n",
  33038. " element.get(0));\n",
  33039. "\n",
  33040. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  33041. " // web socket which is closed, not our websocket->open comm proxy.\n",
  33042. " ws_proxy.onopen();\n",
  33043. "\n",
  33044. " fig.parent_element = element.get(0);\n",
  33045. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  33046. " if (!fig.cell_info) {\n",
  33047. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  33048. " return;\n",
  33049. " }\n",
  33050. "\n",
  33051. " var output_index = fig.cell_info[2]\n",
  33052. " var cell = fig.cell_info[0];\n",
  33053. "\n",
  33054. "};\n",
  33055. "\n",
  33056. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  33057. " var width = fig.canvas.width/mpl.ratio\n",
  33058. " fig.root.unbind('remove')\n",
  33059. "\n",
  33060. " // Update the output cell to use the data from the current canvas.\n",
  33061. " fig.push_to_output();\n",
  33062. " var dataURL = fig.canvas.toDataURL();\n",
  33063. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  33064. " // the notebook keyboard shortcuts fail.\n",
  33065. " IPython.keyboard_manager.enable()\n",
  33066. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  33067. " fig.close_ws(fig, msg);\n",
  33068. "}\n",
  33069. "\n",
  33070. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  33071. " fig.send_message('closing', msg);\n",
  33072. " // fig.ws.close()\n",
  33073. "}\n",
  33074. "\n",
  33075. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  33076. " // Turn the data on the canvas into data in the output cell.\n",
  33077. " var width = this.canvas.width/mpl.ratio\n",
  33078. " var dataURL = this.canvas.toDataURL();\n",
  33079. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  33080. "}\n",
  33081. "\n",
  33082. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  33083. " // Tell IPython that the notebook contents must change.\n",
  33084. " IPython.notebook.set_dirty(true);\n",
  33085. " this.send_message(\"ack\", {});\n",
  33086. " var fig = this;\n",
  33087. " // Wait a second, then push the new image to the DOM so\n",
  33088. " // that it is saved nicely (might be nice to debounce this).\n",
  33089. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  33090. "}\n",
  33091. "\n",
  33092. "mpl.figure.prototype._init_toolbar = function() {\n",
  33093. " var fig = this;\n",
  33094. "\n",
  33095. " var nav_element = $('<div/>')\n",
  33096. " nav_element.attr('style', 'width: 100%');\n",
  33097. " this.root.append(nav_element);\n",
  33098. "\n",
  33099. " // Define a callback function for later on.\n",
  33100. " function toolbar_event(event) {\n",
  33101. " return fig.toolbar_button_onclick(event['data']);\n",
  33102. " }\n",
  33103. " function toolbar_mouse_event(event) {\n",
  33104. " return fig.toolbar_button_onmouseover(event['data']);\n",
  33105. " }\n",
  33106. "\n",
  33107. " for(var toolbar_ind in mpl.toolbar_items){\n",
  33108. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  33109. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  33110. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  33111. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  33112. "\n",
  33113. " if (!name) { continue; };\n",
  33114. "\n",
  33115. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  33116. " button.click(method_name, toolbar_event);\n",
  33117. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  33118. " nav_element.append(button);\n",
  33119. " }\n",
  33120. "\n",
  33121. " // Add the status bar.\n",
  33122. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  33123. " nav_element.append(status_bar);\n",
  33124. " this.message = status_bar[0];\n",
  33125. "\n",
  33126. " // Add the close button to the window.\n",
  33127. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  33128. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  33129. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  33130. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  33131. " buttongrp.append(button);\n",
  33132. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  33133. " titlebar.prepend(buttongrp);\n",
  33134. "}\n",
  33135. "\n",
  33136. "mpl.figure.prototype._root_extra_style = function(el){\n",
  33137. " var fig = this\n",
  33138. " el.on(\"remove\", function(){\n",
  33139. "\tfig.close_ws(fig, {});\n",
  33140. " });\n",
  33141. "}\n",
  33142. "\n",
  33143. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  33144. " // this is important to make the div 'focusable\n",
  33145. " el.attr('tabindex', 0)\n",
  33146. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  33147. " // off when our div gets focus\n",
  33148. "\n",
  33149. " // location in version 3\n",
  33150. " if (IPython.notebook.keyboard_manager) {\n",
  33151. " IPython.notebook.keyboard_manager.register_events(el);\n",
  33152. " }\n",
  33153. " else {\n",
  33154. " // location in version 2\n",
  33155. " IPython.keyboard_manager.register_events(el);\n",
  33156. " }\n",
  33157. "\n",
  33158. "}\n",
  33159. "\n",
  33160. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  33161. " var manager = IPython.notebook.keyboard_manager;\n",
  33162. " if (!manager)\n",
  33163. " manager = IPython.keyboard_manager;\n",
  33164. "\n",
  33165. " // Check for shift+enter\n",
  33166. " if (event.shiftKey && event.which == 13) {\n",
  33167. " this.canvas_div.blur();\n",
  33168. " event.shiftKey = false;\n",
  33169. " // Send a \"J\" for go to next cell\n",
  33170. " event.which = 74;\n",
  33171. " event.keyCode = 74;\n",
  33172. " manager.command_mode();\n",
  33173. " manager.handle_keydown(event);\n",
  33174. " }\n",
  33175. "}\n",
  33176. "\n",
  33177. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  33178. " fig.ondownload(fig, null);\n",
  33179. "}\n",
  33180. "\n",
  33181. "\n",
  33182. "mpl.find_output_cell = function(html_output) {\n",
  33183. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  33184. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  33185. " // IPython event is triggered only after the cells have been serialised, which for\n",
  33186. " // our purposes (turning an active figure into a static one), is too late.\n",
  33187. " var cells = IPython.notebook.get_cells();\n",
  33188. " var ncells = cells.length;\n",
  33189. " for (var i=0; i<ncells; i++) {\n",
  33190. " var cell = cells[i];\n",
  33191. " if (cell.cell_type === 'code'){\n",
  33192. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  33193. " var data = cell.output_area.outputs[j];\n",
  33194. " if (data.data) {\n",
  33195. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  33196. " data = data.data;\n",
  33197. " }\n",
  33198. " if (data['text/html'] == html_output) {\n",
  33199. " return [cell, data, j];\n",
  33200. " }\n",
  33201. " }\n",
  33202. " }\n",
  33203. " }\n",
  33204. "}\n",
  33205. "\n",
  33206. "// Register the function which deals with the matplotlib target/channel.\n",
  33207. "// The kernel may be null if the page has been refreshed.\n",
  33208. "if (IPython.notebook.kernel != null) {\n",
  33209. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  33210. "}\n"
  33211. ],
  33212. "text/plain": [
  33213. "<IPython.core.display.Javascript object>"
  33214. ]
  33215. },
  33216. "metadata": {},
  33217. "output_type": "display_data"
  33218. },
  33219. {
  33220. "data": {
  33221. "text/html": [
  33222. "<img src=\"data:image/png;base64,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Zzx+7pT7XDye+8LRPOiRASZJqs4AA1gsm5N8Kck3krxsPLaU6QPs8fH42TM+1r7x/Gnjr18+/vrpGbd/1Xj+sSN4nPfPaL8BJklqzgADWCzXJ/lRXvhdraVMH2DPj8c3z/hYj+SF3+36+fHX35lx+58azz93BI/TAJMkbcgMMIDF8WtJDiS5ccXxpZx4A2wWT0GUJFVngAEshs0Znnb4tSSnrDi3lBPvKYizGGCSpOoMMIDFcGYO/cDlw/Xh8T7ehEOSpDlngAEshpcluXlG/5ZDw+jmJL893sfb0EuSNOcMMACWMv0piOfHD2KWJGmuGWAALGX6AEuSq8dze5LszPCzw3aPx7bP+HgfyqGnJ+4Y77dnPHbVOh+rASZJqs4AA2ApswdYklye5K4Mb66xP8l9SbYd5mO+a7zd/vF+dyW5bP0P1QCTJHVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQxACTJFVngAHQ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\" width=\"432\">"
  33223. ],
  33224. "text/plain": [
  33225. "<IPython.core.display.HTML object>"
  33226. ]
  33227. },
  33228. "metadata": {},
  33229. "output_type": "display_data"
  33230. },
  33231. {
  33232. "name": "stdout",
  33233. "output_type": "stream",
  33234. "text": [
  33235. "0.0 0.99999976\n",
  33236. "660.02515\n",
  33237. "(369, 315)\n",
  33238. "\n"
  33239. ]
  33240. },
  33241. {
  33242. "data": {
  33243. "application/javascript": [
  33244. "/* Put everything inside the global mpl namespace */\n",
  33245. "window.mpl = {};\n",
  33246. "\n",
  33247. "\n",
  33248. "mpl.get_websocket_type = function() {\n",
  33249. " if (typeof(WebSocket) !== 'undefined') {\n",
  33250. " return WebSocket;\n",
  33251. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  33252. " return MozWebSocket;\n",
  33253. " } else {\n",
  33254. " alert('Your browser does not have WebSocket support.' +\n",
  33255. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  33256. " 'Firefox 4 and 5 are also supported but you ' +\n",
  33257. " 'have to enable WebSockets in about:config.');\n",
  33258. " };\n",
  33259. "}\n",
  33260. "\n",
  33261. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  33262. " this.id = figure_id;\n",
  33263. "\n",
  33264. " this.ws = websocket;\n",
  33265. "\n",
  33266. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  33267. "\n",
  33268. " if (!this.supports_binary) {\n",
  33269. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  33270. " if (warnings) {\n",
  33271. " warnings.style.display = 'block';\n",
  33272. " warnings.textContent = (\n",
  33273. " \"This browser does not support binary websocket messages. \" +\n",
  33274. " \"Performance may be slow.\");\n",
  33275. " }\n",
  33276. " }\n",
  33277. "\n",
  33278. " this.imageObj = new Image();\n",
  33279. "\n",
  33280. " this.context = undefined;\n",
  33281. " this.message = undefined;\n",
  33282. " this.canvas = undefined;\n",
  33283. " this.rubberband_canvas = undefined;\n",
  33284. " this.rubberband_context = undefined;\n",
  33285. " this.format_dropdown = undefined;\n",
  33286. "\n",
  33287. " this.image_mode = 'full';\n",
  33288. "\n",
  33289. " this.root = $('<div/>');\n",
  33290. " this._root_extra_style(this.root)\n",
  33291. " this.root.attr('style', 'display: inline-block');\n",
  33292. "\n",
  33293. " $(parent_element).append(this.root);\n",
  33294. "\n",
  33295. " this._init_header(this);\n",
  33296. " this._init_canvas(this);\n",
  33297. " this._init_toolbar(this);\n",
  33298. "\n",
  33299. " var fig = this;\n",
  33300. "\n",
  33301. " this.waiting = false;\n",
  33302. "\n",
  33303. " this.ws.onopen = function () {\n",
  33304. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  33305. " fig.send_message(\"send_image_mode\", {});\n",
  33306. " if (mpl.ratio != 1) {\n",
  33307. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  33308. " }\n",
  33309. " fig.send_message(\"refresh\", {});\n",
  33310. " }\n",
  33311. "\n",
  33312. " this.imageObj.onload = function() {\n",
  33313. " if (fig.image_mode == 'full') {\n",
  33314. " // Full images could contain transparency (where diff images\n",
  33315. " // almost always do), so we need to clear the canvas so that\n",
  33316. " // there is no ghosting.\n",
  33317. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  33318. " }\n",
  33319. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  33320. " };\n",
  33321. "\n",
  33322. " this.imageObj.onunload = function() {\n",
  33323. " fig.ws.close();\n",
  33324. " }\n",
  33325. "\n",
  33326. " this.ws.onmessage = this._make_on_message_function(this);\n",
  33327. "\n",
  33328. " this.ondownload = ondownload;\n",
  33329. "}\n",
  33330. "\n",
  33331. "mpl.figure.prototype._init_header = function() {\n",
  33332. " var titlebar = $(\n",
  33333. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  33334. " 'ui-helper-clearfix\"/>');\n",
  33335. " var titletext = $(\n",
  33336. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  33337. " 'text-align: center; padding: 3px;\"/>');\n",
  33338. " titlebar.append(titletext)\n",
  33339. " this.root.append(titlebar);\n",
  33340. " this.header = titletext[0];\n",
  33341. "}\n",
  33342. "\n",
  33343. "\n",
  33344. "\n",
  33345. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  33346. "\n",
  33347. "}\n",
  33348. "\n",
  33349. "\n",
  33350. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  33351. "\n",
  33352. "}\n",
  33353. "\n",
  33354. "mpl.figure.prototype._init_canvas = function() {\n",
  33355. " var fig = this;\n",
  33356. "\n",
  33357. " var canvas_div = $('<div/>');\n",
  33358. "\n",
  33359. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  33360. "\n",
  33361. " function canvas_keyboard_event(event) {\n",
  33362. " return fig.key_event(event, event['data']);\n",
  33363. " }\n",
  33364. "\n",
  33365. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  33366. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  33367. " this.canvas_div = canvas_div\n",
  33368. " this._canvas_extra_style(canvas_div)\n",
  33369. " this.root.append(canvas_div);\n",
  33370. "\n",
  33371. " var canvas = $('<canvas/>');\n",
  33372. " canvas.addClass('mpl-canvas');\n",
  33373. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  33374. "\n",
  33375. " this.canvas = canvas[0];\n",
  33376. " this.context = canvas[0].getContext(\"2d\");\n",
  33377. "\n",
  33378. " var backingStore = this.context.backingStorePixelRatio ||\n",
  33379. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  33380. "\tthis.context.mozBackingStorePixelRatio ||\n",
  33381. "\tthis.context.msBackingStorePixelRatio ||\n",
  33382. "\tthis.context.oBackingStorePixelRatio ||\n",
  33383. "\tthis.context.backingStorePixelRatio || 1;\n",
  33384. "\n",
  33385. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  33386. "\n",
  33387. " var rubberband = $('<canvas/>');\n",
  33388. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  33389. "\n",
  33390. " var pass_mouse_events = true;\n",
  33391. "\n",
  33392. " canvas_div.resizable({\n",
  33393. " start: function(event, ui) {\n",
  33394. " pass_mouse_events = false;\n",
  33395. " },\n",
  33396. " resize: function(event, ui) {\n",
  33397. " fig.request_resize(ui.size.width, ui.size.height);\n",
  33398. " },\n",
  33399. " stop: function(event, ui) {\n",
  33400. " pass_mouse_events = true;\n",
  33401. " fig.request_resize(ui.size.width, ui.size.height);\n",
  33402. " },\n",
  33403. " });\n",
  33404. "\n",
  33405. " function mouse_event_fn(event) {\n",
  33406. " if (pass_mouse_events)\n",
  33407. " return fig.mouse_event(event, event['data']);\n",
  33408. " }\n",
  33409. "\n",
  33410. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  33411. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  33412. " // Throttle sequential mouse events to 1 every 20ms.\n",
  33413. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  33414. "\n",
  33415. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  33416. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  33417. "\n",
  33418. " canvas_div.on(\"wheel\", function (event) {\n",
  33419. " event = event.originalEvent;\n",
  33420. " event['data'] = 'scroll'\n",
  33421. " if (event.deltaY < 0) {\n",
  33422. " event.step = 1;\n",
  33423. " } else {\n",
  33424. " event.step = -1;\n",
  33425. " }\n",
  33426. " mouse_event_fn(event);\n",
  33427. " });\n",
  33428. "\n",
  33429. " canvas_div.append(canvas);\n",
  33430. " canvas_div.append(rubberband);\n",
  33431. "\n",
  33432. " this.rubberband = rubberband;\n",
  33433. " this.rubberband_canvas = rubberband[0];\n",
  33434. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  33435. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  33436. "\n",
  33437. " this._resize_canvas = function(width, height) {\n",
  33438. " // Keep the size of the canvas, canvas container, and rubber band\n",
  33439. " // canvas in synch.\n",
  33440. " canvas_div.css('width', width)\n",
  33441. " canvas_div.css('height', height)\n",
  33442. "\n",
  33443. " canvas.attr('width', width * mpl.ratio);\n",
  33444. " canvas.attr('height', height * mpl.ratio);\n",
  33445. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  33446. "\n",
  33447. " rubberband.attr('width', width);\n",
  33448. " rubberband.attr('height', height);\n",
  33449. " }\n",
  33450. "\n",
  33451. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  33452. " // upon first draw.\n",
  33453. " this._resize_canvas(600, 600);\n",
  33454. "\n",
  33455. " // Disable right mouse context menu.\n",
  33456. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  33457. " return false;\n",
  33458. " });\n",
  33459. "\n",
  33460. " function set_focus () {\n",
  33461. " canvas.focus();\n",
  33462. " canvas_div.focus();\n",
  33463. " }\n",
  33464. "\n",
  33465. " window.setTimeout(set_focus, 100);\n",
  33466. "}\n",
  33467. "\n",
  33468. "mpl.figure.prototype._init_toolbar = function() {\n",
  33469. " var fig = this;\n",
  33470. "\n",
  33471. " var nav_element = $('<div/>')\n",
  33472. " nav_element.attr('style', 'width: 100%');\n",
  33473. " this.root.append(nav_element);\n",
  33474. "\n",
  33475. " // Define a callback function for later on.\n",
  33476. " function toolbar_event(event) {\n",
  33477. " return fig.toolbar_button_onclick(event['data']);\n",
  33478. " }\n",
  33479. " function toolbar_mouse_event(event) {\n",
  33480. " return fig.toolbar_button_onmouseover(event['data']);\n",
  33481. " }\n",
  33482. "\n",
  33483. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  33484. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  33485. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  33486. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  33487. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  33488. "\n",
  33489. " if (!name) {\n",
  33490. " // put a spacer in here.\n",
  33491. " continue;\n",
  33492. " }\n",
  33493. " var button = $('<button/>');\n",
  33494. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  33495. " 'ui-button-icon-only');\n",
  33496. " button.attr('role', 'button');\n",
  33497. " button.attr('aria-disabled', 'false');\n",
  33498. " button.click(method_name, toolbar_event);\n",
  33499. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  33500. "\n",
  33501. " var icon_img = $('<span/>');\n",
  33502. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  33503. " icon_img.addClass(image);\n",
  33504. " icon_img.addClass('ui-corner-all');\n",
  33505. "\n",
  33506. " var tooltip_span = $('<span/>');\n",
  33507. " tooltip_span.addClass('ui-button-text');\n",
  33508. " tooltip_span.html(tooltip);\n",
  33509. "\n",
  33510. " button.append(icon_img);\n",
  33511. " button.append(tooltip_span);\n",
  33512. "\n",
  33513. " nav_element.append(button);\n",
  33514. " }\n",
  33515. "\n",
  33516. " var fmt_picker_span = $('<span/>');\n",
  33517. "\n",
  33518. " var fmt_picker = $('<select/>');\n",
  33519. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  33520. " fmt_picker_span.append(fmt_picker);\n",
  33521. " nav_element.append(fmt_picker_span);\n",
  33522. " this.format_dropdown = fmt_picker[0];\n",
  33523. "\n",
  33524. " for (var ind in mpl.extensions) {\n",
  33525. " var fmt = mpl.extensions[ind];\n",
  33526. " var option = $(\n",
  33527. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  33528. " fmt_picker.append(option)\n",
  33529. " }\n",
  33530. "\n",
  33531. " // Add hover states to the ui-buttons\n",
  33532. " $( \".ui-button\" ).hover(\n",
  33533. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  33534. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  33535. " );\n",
  33536. "\n",
  33537. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  33538. " nav_element.append(status_bar);\n",
  33539. " this.message = status_bar[0];\n",
  33540. "}\n",
  33541. "\n",
  33542. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  33543. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  33544. " // which will in turn request a refresh of the image.\n",
  33545. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  33546. "}\n",
  33547. "\n",
  33548. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  33549. " properties['type'] = type;\n",
  33550. " properties['figure_id'] = this.id;\n",
  33551. " this.ws.send(JSON.stringify(properties));\n",
  33552. "}\n",
  33553. "\n",
  33554. "mpl.figure.prototype.send_draw_message = function() {\n",
  33555. " if (!this.waiting) {\n",
  33556. " this.waiting = true;\n",
  33557. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  33558. " }\n",
  33559. "}\n",
  33560. "\n",
  33561. "\n",
  33562. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  33563. " var format_dropdown = fig.format_dropdown;\n",
  33564. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  33565. " fig.ondownload(fig, format);\n",
  33566. "}\n",
  33567. "\n",
  33568. "\n",
  33569. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  33570. " var size = msg['size'];\n",
  33571. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  33572. " fig._resize_canvas(size[0], size[1]);\n",
  33573. " fig.send_message(\"refresh\", {});\n",
  33574. " };\n",
  33575. "}\n",
  33576. "\n",
  33577. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  33578. " var x0 = msg['x0'] / mpl.ratio;\n",
  33579. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  33580. " var x1 = msg['x1'] / mpl.ratio;\n",
  33581. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  33582. " x0 = Math.floor(x0) + 0.5;\n",
  33583. " y0 = Math.floor(y0) + 0.5;\n",
  33584. " x1 = Math.floor(x1) + 0.5;\n",
  33585. " y1 = Math.floor(y1) + 0.5;\n",
  33586. " var min_x = Math.min(x0, x1);\n",
  33587. " var min_y = Math.min(y0, y1);\n",
  33588. " var width = Math.abs(x1 - x0);\n",
  33589. " var height = Math.abs(y1 - y0);\n",
  33590. "\n",
  33591. " fig.rubberband_context.clearRect(\n",
  33592. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  33593. "\n",
  33594. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  33595. "}\n",
  33596. "\n",
  33597. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  33598. " // Updates the figure title.\n",
  33599. " fig.header.textContent = msg['label'];\n",
  33600. "}\n",
  33601. "\n",
  33602. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  33603. " var cursor = msg['cursor'];\n",
  33604. " switch(cursor)\n",
  33605. " {\n",
  33606. " case 0:\n",
  33607. " cursor = 'pointer';\n",
  33608. " break;\n",
  33609. " case 1:\n",
  33610. " cursor = 'default';\n",
  33611. " break;\n",
  33612. " case 2:\n",
  33613. " cursor = 'crosshair';\n",
  33614. " break;\n",
  33615. " case 3:\n",
  33616. " cursor = 'move';\n",
  33617. " break;\n",
  33618. " }\n",
  33619. " fig.rubberband_canvas.style.cursor = cursor;\n",
  33620. "}\n",
  33621. "\n",
  33622. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  33623. " fig.message.textContent = msg['message'];\n",
  33624. "}\n",
  33625. "\n",
  33626. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  33627. " // Request the server to send over a new figure.\n",
  33628. " fig.send_draw_message();\n",
  33629. "}\n",
  33630. "\n",
  33631. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  33632. " fig.image_mode = msg['mode'];\n",
  33633. "}\n",
  33634. "\n",
  33635. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  33636. " // Called whenever the canvas gets updated.\n",
  33637. " this.send_message(\"ack\", {});\n",
  33638. "}\n",
  33639. "\n",
  33640. "// A function to construct a web socket function for onmessage handling.\n",
  33641. "// Called in the figure constructor.\n",
  33642. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  33643. " return function socket_on_message(evt) {\n",
  33644. " if (evt.data instanceof Blob) {\n",
  33645. " /* FIXME: We get \"Resource interpreted as Image but\n",
  33646. " * transferred with MIME type text/plain:\" errors on\n",
  33647. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  33648. " * to be part of the websocket stream */\n",
  33649. " evt.data.type = \"image/png\";\n",
  33650. "\n",
  33651. " /* Free the memory for the previous frames */\n",
  33652. " if (fig.imageObj.src) {\n",
  33653. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  33654. " fig.imageObj.src);\n",
  33655. " }\n",
  33656. "\n",
  33657. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  33658. " evt.data);\n",
  33659. " fig.updated_canvas_event();\n",
  33660. " fig.waiting = false;\n",
  33661. " return;\n",
  33662. " }\n",
  33663. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  33664. " fig.imageObj.src = evt.data;\n",
  33665. " fig.updated_canvas_event();\n",
  33666. " fig.waiting = false;\n",
  33667. " return;\n",
  33668. " }\n",
  33669. "\n",
  33670. " var msg = JSON.parse(evt.data);\n",
  33671. " var msg_type = msg['type'];\n",
  33672. "\n",
  33673. " // Call the \"handle_{type}\" callback, which takes\n",
  33674. " // the figure and JSON message as its only arguments.\n",
  33675. " try {\n",
  33676. " var callback = fig[\"handle_\" + msg_type];\n",
  33677. " } catch (e) {\n",
  33678. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  33679. " return;\n",
  33680. " }\n",
  33681. "\n",
  33682. " if (callback) {\n",
  33683. " try {\n",
  33684. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  33685. " callback(fig, msg);\n",
  33686. " } catch (e) {\n",
  33687. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  33688. " }\n",
  33689. " }\n",
  33690. " };\n",
  33691. "}\n",
  33692. "\n",
  33693. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  33694. "mpl.findpos = function(e) {\n",
  33695. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  33696. " var targ;\n",
  33697. " if (!e)\n",
  33698. " e = window.event;\n",
  33699. " if (e.target)\n",
  33700. " targ = e.target;\n",
  33701. " else if (e.srcElement)\n",
  33702. " targ = e.srcElement;\n",
  33703. " if (targ.nodeType == 3) // defeat Safari bug\n",
  33704. " targ = targ.parentNode;\n",
  33705. "\n",
  33706. " // jQuery normalizes the pageX and pageY\n",
  33707. " // pageX,Y are the mouse positions relative to the document\n",
  33708. " // offset() returns the position of the element relative to the document\n",
  33709. " var x = e.pageX - $(targ).offset().left;\n",
  33710. " var y = e.pageY - $(targ).offset().top;\n",
  33711. "\n",
  33712. " return {\"x\": x, \"y\": y};\n",
  33713. "};\n",
  33714. "\n",
  33715. "/*\n",
  33716. " * return a copy of an object with only non-object keys\n",
  33717. " * we need this to avoid circular references\n",
  33718. " * http://stackoverflow.com/a/24161582/3208463\n",
  33719. " */\n",
  33720. "function simpleKeys (original) {\n",
  33721. " return Object.keys(original).reduce(function (obj, key) {\n",
  33722. " if (typeof original[key] !== 'object')\n",
  33723. " obj[key] = original[key]\n",
  33724. " return obj;\n",
  33725. " }, {});\n",
  33726. "}\n",
  33727. "\n",
  33728. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  33729. " var canvas_pos = mpl.findpos(event)\n",
  33730. "\n",
  33731. " if (name === 'button_press')\n",
  33732. " {\n",
  33733. " this.canvas.focus();\n",
  33734. " this.canvas_div.focus();\n",
  33735. " }\n",
  33736. "\n",
  33737. " var x = canvas_pos.x * mpl.ratio;\n",
  33738. " var y = canvas_pos.y * mpl.ratio;\n",
  33739. "\n",
  33740. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  33741. " step: event.step,\n",
  33742. " guiEvent: simpleKeys(event)});\n",
  33743. "\n",
  33744. " /* This prevents the web browser from automatically changing to\n",
  33745. " * the text insertion cursor when the button is pressed. We want\n",
  33746. " * to control all of the cursor setting manually through the\n",
  33747. " * 'cursor' event from matplotlib */\n",
  33748. " event.preventDefault();\n",
  33749. " return false;\n",
  33750. "}\n",
  33751. "\n",
  33752. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  33753. " // Handle any extra behaviour associated with a key event\n",
  33754. "}\n",
  33755. "\n",
  33756. "mpl.figure.prototype.key_event = function(event, name) {\n",
  33757. "\n",
  33758. " // Prevent repeat events\n",
  33759. " if (name == 'key_press')\n",
  33760. " {\n",
  33761. " if (event.which === this._key)\n",
  33762. " return;\n",
  33763. " else\n",
  33764. " this._key = event.which;\n",
  33765. " }\n",
  33766. " if (name == 'key_release')\n",
  33767. " this._key = null;\n",
  33768. "\n",
  33769. " var value = '';\n",
  33770. " if (event.ctrlKey && event.which != 17)\n",
  33771. " value += \"ctrl+\";\n",
  33772. " if (event.altKey && event.which != 18)\n",
  33773. " value += \"alt+\";\n",
  33774. " if (event.shiftKey && event.which != 16)\n",
  33775. " value += \"shift+\";\n",
  33776. "\n",
  33777. " value += 'k';\n",
  33778. " value += event.which.toString();\n",
  33779. "\n",
  33780. " this._key_event_extra(event, name);\n",
  33781. "\n",
  33782. " this.send_message(name, {key: value,\n",
  33783. " guiEvent: simpleKeys(event)});\n",
  33784. " return false;\n",
  33785. "}\n",
  33786. "\n",
  33787. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  33788. " if (name == 'download') {\n",
  33789. " this.handle_save(this, null);\n",
  33790. " } else {\n",
  33791. " this.send_message(\"toolbar_button\", {name: name});\n",
  33792. " }\n",
  33793. "};\n",
  33794. "\n",
  33795. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  33796. " this.message.textContent = tooltip;\n",
  33797. "};\n",
  33798. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  33799. "\n",
  33800. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  33801. "\n",
  33802. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  33803. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  33804. " // object with the appropriate methods. Currently this is a non binary\n",
  33805. " // socket, so there is still some room for performance tuning.\n",
  33806. " var ws = {};\n",
  33807. "\n",
  33808. " ws.close = function() {\n",
  33809. " comm.close()\n",
  33810. " };\n",
  33811. " ws.send = function(m) {\n",
  33812. " //console.log('sending', m);\n",
  33813. " comm.send(m);\n",
  33814. " };\n",
  33815. " // Register the callback with on_msg.\n",
  33816. " comm.on_msg(function(msg) {\n",
  33817. " //console.log('receiving', msg['content']['data'], msg);\n",
  33818. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  33819. " ws.onmessage(msg['content']['data'])\n",
  33820. " });\n",
  33821. " return ws;\n",
  33822. "}\n",
  33823. "\n",
  33824. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  33825. " // This is the function which gets called when the mpl process\n",
  33826. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  33827. "\n",
  33828. " var id = msg.content.data.id;\n",
  33829. " // Get hold of the div created by the display call when the Comm\n",
  33830. " // socket was opened in Python.\n",
  33831. " var element = $(\"#\" + id);\n",
  33832. " var ws_proxy = comm_websocket_adapter(comm)\n",
  33833. "\n",
  33834. " function ondownload(figure, format) {\n",
  33835. " window.open(figure.imageObj.src);\n",
  33836. " }\n",
  33837. "\n",
  33838. " var fig = new mpl.figure(id, ws_proxy,\n",
  33839. " ondownload,\n",
  33840. " element.get(0));\n",
  33841. "\n",
  33842. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  33843. " // web socket which is closed, not our websocket->open comm proxy.\n",
  33844. " ws_proxy.onopen();\n",
  33845. "\n",
  33846. " fig.parent_element = element.get(0);\n",
  33847. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  33848. " if (!fig.cell_info) {\n",
  33849. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  33850. " return;\n",
  33851. " }\n",
  33852. "\n",
  33853. " var output_index = fig.cell_info[2]\n",
  33854. " var cell = fig.cell_info[0];\n",
  33855. "\n",
  33856. "};\n",
  33857. "\n",
  33858. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  33859. " var width = fig.canvas.width/mpl.ratio\n",
  33860. " fig.root.unbind('remove')\n",
  33861. "\n",
  33862. " // Update the output cell to use the data from the current canvas.\n",
  33863. " fig.push_to_output();\n",
  33864. " var dataURL = fig.canvas.toDataURL();\n",
  33865. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  33866. " // the notebook keyboard shortcuts fail.\n",
  33867. " IPython.keyboard_manager.enable()\n",
  33868. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  33869. " fig.close_ws(fig, msg);\n",
  33870. "}\n",
  33871. "\n",
  33872. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  33873. " fig.send_message('closing', msg);\n",
  33874. " // fig.ws.close()\n",
  33875. "}\n",
  33876. "\n",
  33877. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  33878. " // Turn the data on the canvas into data in the output cell.\n",
  33879. " var width = this.canvas.width/mpl.ratio\n",
  33880. " var dataURL = this.canvas.toDataURL();\n",
  33881. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  33882. "}\n",
  33883. "\n",
  33884. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  33885. " // Tell IPython that the notebook contents must change.\n",
  33886. " IPython.notebook.set_dirty(true);\n",
  33887. " this.send_message(\"ack\", {});\n",
  33888. " var fig = this;\n",
  33889. " // Wait a second, then push the new image to the DOM so\n",
  33890. " // that it is saved nicely (might be nice to debounce this).\n",
  33891. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  33892. "}\n",
  33893. "\n",
  33894. "mpl.figure.prototype._init_toolbar = function() {\n",
  33895. " var fig = this;\n",
  33896. "\n",
  33897. " var nav_element = $('<div/>')\n",
  33898. " nav_element.attr('style', 'width: 100%');\n",
  33899. " this.root.append(nav_element);\n",
  33900. "\n",
  33901. " // Define a callback function for later on.\n",
  33902. " function toolbar_event(event) {\n",
  33903. " return fig.toolbar_button_onclick(event['data']);\n",
  33904. " }\n",
  33905. " function toolbar_mouse_event(event) {\n",
  33906. " return fig.toolbar_button_onmouseover(event['data']);\n",
  33907. " }\n",
  33908. "\n",
  33909. " for(var toolbar_ind in mpl.toolbar_items){\n",
  33910. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  33911. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  33912. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  33913. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  33914. "\n",
  33915. " if (!name) { continue; };\n",
  33916. "\n",
  33917. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  33918. " button.click(method_name, toolbar_event);\n",
  33919. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  33920. " nav_element.append(button);\n",
  33921. " }\n",
  33922. "\n",
  33923. " // Add the status bar.\n",
  33924. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  33925. " nav_element.append(status_bar);\n",
  33926. " this.message = status_bar[0];\n",
  33927. "\n",
  33928. " // Add the close button to the window.\n",
  33929. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  33930. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  33931. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  33932. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  33933. " buttongrp.append(button);\n",
  33934. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  33935. " titlebar.prepend(buttongrp);\n",
  33936. "}\n",
  33937. "\n",
  33938. "mpl.figure.prototype._root_extra_style = function(el){\n",
  33939. " var fig = this\n",
  33940. " el.on(\"remove\", function(){\n",
  33941. "\tfig.close_ws(fig, {});\n",
  33942. " });\n",
  33943. "}\n",
  33944. "\n",
  33945. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  33946. " // this is important to make the div 'focusable\n",
  33947. " el.attr('tabindex', 0)\n",
  33948. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  33949. " // off when our div gets focus\n",
  33950. "\n",
  33951. " // location in version 3\n",
  33952. " if (IPython.notebook.keyboard_manager) {\n",
  33953. " IPython.notebook.keyboard_manager.register_events(el);\n",
  33954. " }\n",
  33955. " else {\n",
  33956. " // location in version 2\n",
  33957. " IPython.keyboard_manager.register_events(el);\n",
  33958. " }\n",
  33959. "\n",
  33960. "}\n",
  33961. "\n",
  33962. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  33963. " var manager = IPython.notebook.keyboard_manager;\n",
  33964. " if (!manager)\n",
  33965. " manager = IPython.keyboard_manager;\n",
  33966. "\n",
  33967. " // Check for shift+enter\n",
  33968. " if (event.shiftKey && event.which == 13) {\n",
  33969. " this.canvas_div.blur();\n",
  33970. " event.shiftKey = false;\n",
  33971. " // Send a \"J\" for go to next cell\n",
  33972. " event.which = 74;\n",
  33973. " event.keyCode = 74;\n",
  33974. " manager.command_mode();\n",
  33975. " manager.handle_keydown(event);\n",
  33976. " }\n",
  33977. "}\n",
  33978. "\n",
  33979. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  33980. " fig.ondownload(fig, null);\n",
  33981. "}\n",
  33982. "\n",
  33983. "\n",
  33984. "mpl.find_output_cell = function(html_output) {\n",
  33985. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  33986. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  33987. " // IPython event is triggered only after the cells have been serialised, which for\n",
  33988. " // our purposes (turning an active figure into a static one), is too late.\n",
  33989. " var cells = IPython.notebook.get_cells();\n",
  33990. " var ncells = cells.length;\n",
  33991. " for (var i=0; i<ncells; i++) {\n",
  33992. " var cell = cells[i];\n",
  33993. " if (cell.cell_type === 'code'){\n",
  33994. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  33995. " var data = cell.output_area.outputs[j];\n",
  33996. " if (data.data) {\n",
  33997. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  33998. " data = data.data;\n",
  33999. " }\n",
  34000. " if (data['text/html'] == html_output) {\n",
  34001. " return [cell, data, j];\n",
  34002. " }\n",
  34003. " }\n",
  34004. " }\n",
  34005. " }\n",
  34006. "}\n",
  34007. "\n",
  34008. "// Register the function which deals with the matplotlib target/channel.\n",
  34009. "// The kernel may be null if the page has been refreshed.\n",
  34010. "if (IPython.notebook.kernel != null) {\n",
  34011. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  34012. "}\n"
  34013. ],
  34014. "text/plain": [
  34015. "<IPython.core.display.Javascript object>"
  34016. ]
  34017. },
  34018. "metadata": {},
  34019. "output_type": "display_data"
  34020. },
  34021. {
  34022. "data": {
  34023. "text/html": [
  34024. "<img src=\"data:image/png;base64,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\" width=\"432\">"
  34025. ],
  34026. "text/plain": [
  34027. "<IPython.core.display.HTML object>"
  34028. ]
  34029. },
  34030. "metadata": {},
  34031. "output_type": "display_data"
  34032. }
  34033. ],
  34034. "source": [
  34035. "# prediction\n",
  34036. "from numpy import unravel_index\n",
  34037. "import math\n",
  34038. "%matplotlib notebook\n",
  34039. "# %matplotlib widget\n",
  34040. "\n",
  34041. "\n",
  34042. "model.eval() # Set model to evaluate mode\n",
  34043. "\n",
  34044. "# test_dataset = SimDataset(2, transform = trans)\n",
  34045. "test_set = SimDataset(\n",
  34046. " main_dir=val_dataset_path, \n",
  34047. "# main_dir=train_dataset_path,\n",
  34048. " transform=None\n",
  34049. ")\n",
  34050. "\n",
  34051. "test_batch_size = 8\n",
  34052. "test_loader = DataLoader(test_set, batch_size=test_batch_size , shuffle=True, num_workers=num_workers)\n",
  34053. "inputs, labels = next(iter(test_loader))\n",
  34054. "\n",
  34055. "# for i in range(4):\n",
  34056. "mask_prob = 0.4\n",
  34057. "outputs = []\n",
  34058. "\n",
  34059. "for i in range(test_batch_size):\n",
  34060. " img_num = i\n",
  34061. " test_image = inputs.cpu()[img_num][0].numpy()\n",
  34062. " test_mask = labels.cpu()[img_num][0].numpy()\n",
  34063. "\n",
  34064. " inputs = inputs.to(device, dtype=torch.float)\n",
  34065. " labels = labels.to(device, dtype=torch.float)\n",
  34066. "# pred = F.sigmoid(pred)\n",
  34067. "\n",
  34068. " pred = model(inputs)\n",
  34069. " pred = F.sigmoid(pred)\n",
  34070. " pred = pred.data.cpu().numpy()\n",
  34071. " # pred = pred.data.cpu()\n",
  34072. "\n",
  34073. "\n",
  34074. "\n",
  34075. " predImg = pred[img_num][0]\n",
  34076. " predMask = np.where(predImg > mask_prob, 1, 0)\n",
  34077. "\n",
  34078. " imgs = []\n",
  34079. " imgs.append(test_image)\n",
  34080. " imgs.append(test_mask)\n",
  34081. " imgs.append(predMask)\n",
  34082. " outputs.append(predMask)\n",
  34083. " imgs.append(predImg)\n",
  34084. " printImages(imgs)"
  34085. ]
  34086. },
  34087. {
  34088. "cell_type": "code",
  34089. "execution_count": 27,
  34090. "metadata": {},
  34091. "outputs": [],
  34092. "source": [
  34093. "SMOOTH = 1e-6\n",
  34094. "\n",
  34095. "def iou_pytorch(outputs: torch.Tensor, labels: torch.Tensor):\n",
  34096. " # You can comment out this line if you are passing tensors of equal shape\n",
  34097. " # But if you are passing output from UNet or something it will most probably\n",
  34098. " # be with the BATCH x 1 x H x W shape\n",
  34099. "# outputs = outputs.squeeze(1) # BATCH x 1 x H x W => BATCH x H x W\n",
  34100. " labels = labels.squeeze(1)\n",
  34101. " \n",
  34102. " intersection = (outputs & labels).float().sum((1, 2)) # Will be zero if Truth=0 or Prediction=0\n",
  34103. "# intersection = (outputs & labels).float().sum() # Will be zero if Truth=0 or Prediction=0\n",
  34104. " \n",
  34105. " union = (outputs | labels).float().sum((1, 2)) # Will be zzero if both are 0\n",
  34106. " iou = (intersection + SMOOTH) / (union + SMOOTH) # We smooth our devision to avoid 0/0\n",
  34107. "\n",
  34108. " \n",
  34109. " thresholded = torch.clamp(20 * (iou - 0.5), 0, 10).ceil() / 10 # This is equal to comparing with thresolds\n",
  34110. " \n",
  34111. "# return thresholded # Or thresholded.mean() if you are interested in average across the batch\n",
  34112. " return iou * 100\n",
  34113. " \n",
  34114. "# Numpy version\n",
  34115. "# Well, it's the same function, so I'm going to omit the comments\n",
  34116. "\n",
  34117. "def iou_numpy(outputs: np.array, labels: np.array):\n",
  34118. " outputs = outputs.squeeze(1)\n",
  34119. " \n",
  34120. " intersection = (outputs & labels).sum((1, 2))\n",
  34121. " union = (outputs | labels).sum((1, 2))\n",
  34122. " \n",
  34123. " iou = (intersection + SMOOTH) / (union + SMOOTH)\n",
  34124. " \n",
  34125. " thresholded = np.ceil(np.clip(20 * (iou - 0.5), 0, 10)) / 10\n",
  34126. " \n",
  34127. " return thresholded # Or thresholded.mean()\n"
  34128. ]
  34129. },
  34130. {
  34131. "cell_type": "code",
  34132. "execution_count": 22,
  34133. "metadata": {},
  34134. "outputs": [
  34135. {
  34136. "name": "stdout",
  34137. "output_type": "stream",
  34138. "text": [
  34139. "tensor([95.1684, 95.1100, 95.9519, 91.4286, 96.5347, 94.8798, 93.9828, 92.2917])\n",
  34140. "tensor(94.4185)\n"
  34141. ]
  34142. }
  34143. ],
  34144. "source": [
  34145. "# print(labels.cpu().shape)\n",
  34146. "# print(len(outputs))\n",
  34147. "outputs = np.array(outputs)\n",
  34148. "# print(labels.shape)\n",
  34149. "# print(outputs.shape)\n",
  34150. "\n",
  34151. "outputs = torch.from_numpy(outputs)\n",
  34152. "outputs = outputs.cpu().long()\n",
  34153. "labels = labels.cpu().long()\n",
  34154. "\n",
  34155. "iou = iou_pytorch(outputs.cpu(), labels.cpu())\n",
  34156. "print(iou)\n",
  34157. "print(iou.mean())\n",
  34158. "# taret.cpu().long()"
  34159. ]
  34160. },
  34161. {
  34162. "cell_type": "code",
  34163. "execution_count": 23,
  34164. "metadata": {},
  34165. "outputs": [],
  34166. "source": [
  34167. "# torch.save(model.state_dict(), './best_model.pt')\n",
  34168. "# m = pytorch_unet.UNet(n_out_class).to(device, dtype=torch.float)\n",
  34169. "# m.load_state_dict(torch.load('./best_model.pt'))\n",
  34170. "# print(m)"
  34171. ]
  34172. },
  34173. {
  34174. "cell_type": "code",
  34175. "execution_count": null,
  34176. "metadata": {},
  34177. "outputs": [],
  34178. "source": []
  34179. },
  34180. {
  34181. "cell_type": "code",
  34182. "execution_count": 24,
  34183. "metadata": {},
  34184. "outputs": [],
  34185. "source": [
  34186. "# print(np.amax(pred[0][0]))\n",
  34187. "# plt.imshow(img)"
  34188. ]
  34189. },
  34190. {
  34191. "cell_type": "code",
  34192. "execution_count": 25,
  34193. "metadata": {},
  34194. "outputs": [],
  34195. "source": [
  34196. "# inputs, masks = next(iter(dataloaders['train']))\n",
  34197. "# inputs = inputs.to(device)\n"
  34198. ]
  34199. },
  34200. {
  34201. "cell_type": "raw",
  34202. "metadata": {},
  34203. "source": [
  34204. "# import logging\n",
  34205. "\n",
  34206. "\n",
  34207. "# # img_grid = torchvision.utils.make_grid(inputs)\n",
  34208. "# # writer.add_image(\"train image\", img_grid)\n",
  34209. "# writer.add_graph(model, inputs)\n",
  34210. "# writer.close()"
  34211. ]
  34212. }
  34213. ],
  34214. "metadata": {
  34215. "kernelspec": {
  34216. "display_name": "Python 3",
  34217. "language": "python",
  34218. "name": "python3"
  34219. },
  34220. "language_info": {
  34221. "codemirror_mode": {
  34222. "name": "ipython",
  34223. "version": 3
  34224. },
  34225. "file_extension": ".py",
  34226. "mimetype": "text/x-python",
  34227. "name": "python",
  34228. "nbconvert_exporter": "python",
  34229. "pygments_lexer": "ipython3",
  34230. "version": "3.7.9"
  34231. }
  34232. },
  34233. "nbformat": 4,
  34234. "nbformat_minor": 4
  34235. }