1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693# 1 "src/owl/misc/owl_plot.ml"(*
* OWL - an OCaml numerical library for scientific computing
* Copyright (c) 2016-2018 Liang Wang <liang.wang@cl.cam.ac.uk>
*)(** Plot Module *)(* types in plot module *)typedsmat=Owl_dense_matrix.D.mattypecolor=RED|GREEN|BLUEtypelegend_typ=LINE|SCATTER|BOXtypelegend_position=North|South|West|East|NorthWest|NorthEast|SouthWest|SouthEasttypelegend_item={mutableplot_type:legend_typ;mutableline_style:int;mutableline_color:int*int*int;mutablemarker:string;mutablemarker_color:int*int*int;mutablefill_pattern:int;mutablefill_color:int*int*int;}typepage={mutabletitle:string;mutablefgcolor:int*int*int;mutablefontsize:float;mutableis_3d:bool;mutableno_axes:bool;(* control axis labels *)mutablexlabel:string;mutableylabel:string;mutablezlabel:string;(* control axis ranges *)mutablexrange:float*float;mutableyrange:float*float;mutablezrange:float*float;mutableauto_xrange:bool;mutableauto_yrange:bool;mutableauto_zrange:bool;(* control tick labels *)mutablexticklabels:(float*string)list;mutableyticklabels:(float*string)list;mutablezticklabels:(float*string)list;(* control axis log scale *)mutablexlogscale:bool;mutableylogscale:bool;(* control grids *)mutablexgrid:bool;mutableygrid:bool;mutablezgrid:bool;(* viewing perspective for 3D plots
* http://plplot.sourceforge.net/docbook-manual/plplot-html-5.12.0/plw3d.html *)mutablealtitude:float;mutableazimuth:float;(* control legend *)mutablelegend:bool;mutablelegend_position:legend_position;mutablelegend_items:legend_itemarray;mutablelegend_names:stringarray;(* cache the plot operations *)mutableplots:(unit->unit)array;}typehandle={mutableholdon:bool;mutableoutput:string;mutablebgcolor:int*int*int;mutablepensize:float;mutablepage_size:int*int;(* control the sub plots *)mutableshape:int*int;mutablepages:pagearray;mutablecurrent_page:int;}typeaxis=X|Y|Z|XY|XZ|YZ|XYZ(* Specification to configure a plot *)typespec=|RGBofint*int*int|LineStyleofint|LineWidthoffloat|Markerofstring|MarkerSizeoffloat|Fill|FillPatternofint|Contour|Altitudeoffloat|Azimuthoffloat|ZLineofaxis|NoMagColor|Curtain|Faceted|Axisofaxislet_get_rgbldefault_val=letl=l|>List.filter(functionRGB_->true|_->false)|>List.map(functionRGB(r,g,b)->(r,g,b)|_->default_val)inletk=List.lengthlinifk=0thendefault_valelseList.nthl(k-1)let_get_line_styleldefault_val=letl=l|>List.filter(functionLineStyle_->true|_->false)|>List.map(functionLineStylex->x|_->default_val)inletk=List.lengthlinifk=0thendefault_valelseList.nthl(k-1)let_get_line_widthldefault_val=letl=l|>List.filter(functionLineWidth_->true|_->false)|>List.map(functionLineWidthx->x|_->default_val)inletk=List.lengthlinifk=0thendefault_valelseList.nthl(k-1)let_get_markerldefault_val=letl=l|>List.filter(functionMarker_->true|_->false)|>List.map(functionMarkerx->x|_->default_val)inletk=List.lengthlinifk=0thendefault_valelseList.nthl(k-1)let_get_marker_sizeldefault_val=letl=l|>List.filter(functionMarkerSize_->true|_->false)|>List.map(functionMarkerSizex->x|_->default_val)inletk=List.lengthlinifk=0thendefault_valelseList.nthl(k-1)let_get_fillldefault_val=letl=l|>List.filter(functionFill->true|_->false)|>List.map(functionFill->true|_->default_val)inletk=List.lengthlinifk=0thendefault_valelseList.nthl(k-1)let_get_fill_patternldefault_val=letl=l|>List.filter(functionFillPattern_->true|_->false)|>List.map(functionFillPatternx->x|_->default_val)inletk=List.lengthlinifk=0thendefault_valelseList.nthl(k-1)let_get_contourldefault_val=letl=l|>List.filter(functionContour->true|_->false)|>List.map(functionContour->true|_->default_val)inletk=List.lengthlinifk=0thendefault_valelseList.nthl(k-1)let_get_altitudeldefault_val=letl=l|>List.filter(functionAltitude_->true|_->false)|>List.map(functionAltitudex->x|_->default_val)inletk=List.lengthlinifk=0thendefault_valelseList.nthl(k-1)let_get_azimuthldefault_val=letl=l|>List.filter(functionAzimuth_->true|_->false)|>List.map(functionAzimuthx->x|_->default_val)inletk=List.lengthlinifk=0thendefault_valelseList.nthl(k-1)let_get_zlineldefault_val=letl=l|>List.filter(functionZLine_->true|_->false)|>List.map(function|ZLineX->Plplot.PL_DRAW_LINEX|ZLineY->Plplot.PL_DRAW_LINEY|ZLineXY->Plplot.PL_DRAW_LINEXY|_->default_val)inletk=List.lengthlinifk=0thendefault_valelseList.nthl(k-1)let_get_mag_colorldefault_val=letl=l|>List.filter(functionNoMagColor->true|_->false)|>List.map(functionNoMagColor->false|_->true)inletk=List.lengthlinifk=0thendefault_valelseList.nthl(k-1)let_get_curtainldefault_val=letl=l|>List.filter(functionCurtain->true|_->false)|>List.map(functionCurtain->true|_->false)inletk=List.lengthlinifk=0thendefault_valelseList.nthl(k-1)let_get_facetedldefault_val=letl=l|>List.filter(functionFaceted->true|_->false)|>List.map(functionFaceted->true|_->false)inletk=List.lengthlinifk=0thendefault_valelseList.nthl(k-1)let_get_axisldefault_val=letl=l|>List.filter(functionAxis_->true|_->false)|>List.map(functionAxisx->x|_->default_val)inletk=List.lengthlinifk=0thendefault_valelseList.nthl(k-1)(* module functions to simplify plotting *)let_create_page()={title="";fgcolor=(255,0,0);fontsize=-1.;is_3d=false;no_axes=false;xlabel="x";ylabel="y";zlabel="z";xrange=(infinity,neg_infinity);yrange=(infinity,neg_infinity);zrange=(infinity,neg_infinity);auto_xrange=true;auto_yrange=true;auto_zrange=true;xticklabels=[];yticklabels=[];zticklabels=[];xlogscale=false;ylogscale=false;xgrid=false;ygrid=false;zgrid=false;altitude=33.;azimuth=45.;legend=false;legend_position=NorthEast;legend_items=[||];legend_names=[||];plots=[||];}let_create_handle()={holdon=true;output="";bgcolor=(0,0,0);pensize=0.;page_size=(0,0);shape=(1,1);current_page=0;pages=[|_create_page()|];}letcreate?(m=1)?(n=1)s=letpages=Array.make(m*n)None|>Array.map(fun_->_create_page())inleth=_create_handle()inh.shape<-(m,n);h.pages<-pages;h.output<-s;hlet_default_handle=leth=_create_handle()inh.holdon<-false;hlet_supported_device=["aqt";"xwin";"pdf";"ps";"psc";"png";"svg";"xfig";"psttf";"psttc";"xcairo";"pdfcairo";"epscairo";"pscairo";"svgcairo";"pngcairo";"memcairo";"extcairo"]let_set_deviceh=tryletx=Owl_utils.get_suffixh.outputinPlplot.plsdevx;Plplot.plsfnamh.output;withexn->()let_add_legend_itempplot_typeline_styleline_colormarkermarker_colorfill_patternfill_color=letitem={plot_type=plot_type;line_style=line_style;line_color=line_color;marker=marker;marker_color=marker_color;fill_pattern=fill_pattern;fill_color=fill_color;}inp.legend_items<-Array.appendp.legend_items[|item|]let_plplot_positionpos=letopenPlplotinmatchposwith|North->[PL_POSITION_TOP]|South->[PL_POSITION_BOTTOM]|West->[PL_POSITION_LEFT]|East->[PL_POSITION_RIGHT]|NorthWest->[PL_POSITION_TOP;PL_POSITION_LEFT]|NorthEast->[PL_POSITION_TOP;PL_POSITION_RIGHT]|SouthWest->[PL_POSITION_BOTTOM;PL_POSITION_LEFT]|SouthEast->[PL_POSITION_BOTTOM;PL_POSITION_RIGHT]let_draw_legendp=letopenPlplotinlet_=plscmap0n64inletcbase=16inletopt=[PL_LEGEND_BOUNDING_BOX]inletposition=_plplot_positionp.legend_position@[PL_POSITION_INSIDE]inletopt_array=Array.map(funitem->matchitem.plot_typewith|LINE->[PL_LEGEND_LINE;PL_LEGEND_SYMBOL]|SCATTER->[PL_LEGEND_SYMBOL]|BOX->[PL_LEGEND_COLOR_BOX])p.legend_itemsinlettext_colors=Array.map(fun_->1)p.legend_itemsinlettext=Array.mapi(funi_->p.legend_names.(i))p.legend_itemsinletline_colors=Array.mapi(funix->letr,g,b=x.line_colorinplscol0(i+cbase)rgb;(i+cbase))p.legend_itemsinletline_styles=Array.map(funx->x.line_style)p.legend_itemsinletline_widths=Array.map(fun_->1.)p.legend_itemsinletmarker_colors=line_colorsinletmarker_scales=Array.map(fun_->1.)p.legend_itemsinletmarker_nums=Array.map(fun_->3)p.legend_itemsinletmarkers=Array.map(funx->x.marker)p.legend_itemsinletbox_colors=line_colorsinletbox_patterns=Array.map(funx->x.fill_pattern)p.legend_itemsinletbox_scales=Array.map(funx->0.8)p.legend_itemsinletbox_linewidths=Array.map(funx->1.)p.legend_itemsinlet_=pllegendoptposition0.050.050.1151100opt_array1.01.02.01.0text_colorstextbox_colorsbox_patternsbox_scalesbox_linewidthsline_colorsline_stylesline_widthsmarker_colorsmarker_scalesmarker_numsmarkersin()let_calculate_paper_sizemn=letmax_w,max_h=900.,900.inletr0=4./.3.inletcur_w,cur_h=r0*.(float_of_intn),float_of_intminletr1=max_w/.max_hinletr2=cur_w/.cur_hinletw,h=match(r1/.r2)<1.with|true->max_w,max_w/.r2|false->max_h*.r2,max_hinint_of_floatw,int_of_floath(* calculate the axis config based on a page config *)let_config_2d_axisp=letbase=0inifp.no_axesthen-1elseletresidual=if(p.xlogscale,p.ylogscale)=(true,false)then10elseif(p.xlogscale,p.ylogscale)=(false,true)then20elseif(p.xlogscale,p.ylogscale)=(true,true)then30elseifp.xticklabels|>List.length>0||p.yticklabels|>List.length>0then70else0inbase+residuallet_initialiseh=letopenPlplotin(* configure before init *)_set_deviceh;letr,g,b=h.bgcolorinplscolbgrgb;(* init the plot *)letm,n=h.shapeinifnot(h.shape=(1,1))thenplssubnm;letx,y=matchh.page_size=(0,0)with|true->_calculate_paper_sizemn|false->h.page_sizeinplspage0.0.xy00;plinit();(* configure after init *)plwidthh.pensize(* callback function of drawing customised tick labels *)let_draw_ticklabelspaxisvalue=letopenPlplotinletl=matchaxiswith|PL_X_AXIS->p.xticklabels|PL_Y_AXIS->p.yticklabels|PL_Z_AXIS->p.zticklabelsintryList.assocvaluelwithexn->Printf.sprintf"%g"valuelet_prepare_pagep=letopenPlplotin(* customise tick labels if necessary *)plslabelfunc(_draw_ticklabelsp);(* configure an individual page *)letr,g,b=p.fgcolorinplscol02rgb;plcol02;ifp.fontsize>0.thenplschrp.fontsize1.0;letxmin,xmax=p.xrangeinletymin,ymax=p.yrangeinletzmin,zmax=p.zrangeinletalt,az=p.altitude,p.azimuthinifnotp.is_3dthen((* prepare a 2D plot *)plenvxminxmaxyminymax0(_config_2d_axisp))else((* prepare a 3D plot *)pladv0;plvpor0.01.00.00.9;plwind(-1.0)1.0(-1.0)1.5;plw3d1.01.01.2xminxmaxyminymaxzminzmaxaltaz;plbox3"bntu"p.xlabel0.00"bntu"p.ylabel0.00"bcdfntu"p.zlabel0.04);(* set x-label, y-label, and title *)pllabp.xlabelp.ylabelp.title;(* reset foreground colour to index 1 *)plcol01;ifp.legendthen_draw_legendplet_finalise()=(* play safe, reset pages in default_handle *)_default_handle.pages<-[|_create_page()|];Plplot.plend()letoutputh=h.holdon<-false;_initialiseh;Array.iteri(funip->ifi>0thenPlplot.pladvi;_prepare_pagep;Array.iter(funf->f())p.plots)h.pages;_finalise()letset_outpuths=letx=Owl_utils.get_suffixsinmatch(List.memx_supported_device)with|true->h.output<-s|false->Owl_log.error"unsupported file type."letset_titlehs=(h.pages.(h.current_page)).title<-sletset_xlabelhs=(h.pages.(h.current_page)).xlabel<-sletset_ylabelhs=(h.pages.(h.current_page)).ylabel<-sletset_zlabelhs=(h.pages.(h.current_page)).zlabel<-sletset_xrangehab=(h.pages.(h.current_page)).auto_xrange<-false;(h.pages.(h.current_page)).xrange<-(a,b)letset_yrangehab=(h.pages.(h.current_page)).auto_yrange<-false;(h.pages.(h.current_page)).yrange<-(a,b)letset_zrangehab=(h.pages.(h.current_page)).auto_zrange<-false;(h.pages.(h.current_page)).zrange<-(a,b)letset_xticklabelshl=(h.pages.(h.current_page)).xticklabels<-lletset_yticklabelshl=(h.pages.(h.current_page)).yticklabels<-lletset_zticklabelshl=(h.pages.(h.current_page)).zticklabels<-lletset_foreground_colorhrgb=(h.pages.(h.current_page)).fgcolor<-(r,g,b)letset_background_colorhrgb=h.bgcolor<-(r,g,b)letset_font_sizehx=(h.pages.(h.current_page)).fontsize<-xletset_pen_sizehx=h.pensize<-xletset_page_sizehxy=h.page_size<-(x,y)letlegend_onh?(position=NorthEast)s=(h.pages.(h.current_page)).legend<-true;(h.pages.(h.current_page)).legend_position<-position;(h.pages.(h.current_page)).legend_names<-sletlegend_offh=(h.pages.(h.current_page)).legend<-false(* TODO *)letrgb=None(*FIXME: plptex3 to write text inside the viewport of a 3D plot*)lettext?(h=_default_handle)?(spec=[])xy?(dx=0.)?(dy=0.)s=letopenPlplotin(* prepare the closure *)letp=h.pages.(h.current_page)inletcolor=_get_rgbspecp.fgcolorinletr,g,b=colorin(* drawing function *)letf=(fun()->(*save original color index*)letr',g',b'=plgcol01inplscol01rgb;plcol01;plptexxydxdy0.s;(* restore original settings *)plscol01r'g'b';plcol01)in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];ifnoth.holdonthenoutputhlet_thinningx=letl=float_of_int(Array.lengthx)inletn=ifl<16.thenlelse16.inletc=float_of_int(Array.lengthx)/.ninArray.init(int_of_floatn)(funi->x.(int_of_float(float_of_inti*.c)))let_union_rangeprx=leta,b=rinletm,n=Owl_stats.minmaxxinletc=ifa<mthenaelseminletd=ifb>nthenbelseninlete=(d-.c)*.pinc-.e,d+.elet_adjust_range?(margin=0.)hdaxis=letp=h.pages.(h.current_page)inmatchaxiswith|X->ifp.auto_xrangethenp.xrange<-_union_rangemarginp.xranged|Y->ifp.auto_yrangethenp.yrange<-_union_rangemarginp.yranged|Z->ifp.auto_zrangethenp.zrange<-_union_rangemarginp.zranged|_->failwith"owl_plot:_adjust_range"letplot?(h=_default_handle)?(spec=[])xy=letopenPlplotinletx=Owl_dense_matrix.D.to_arrayxinlety=Owl_dense_matrix.D.to_arrayyin_adjust_rangehxX;_adjust_rangehyY;(* prepare the closure *)letp=h.pages.(h.current_page)inletcolor=_get_rgbspecp.fgcolorinletr,g,b=colorinletmarker=_get_markerspec""inletmarker_size=_get_marker_sizespec4.inletline_style=_get_line_stylespec1inletline_width=_get_line_widthspec(-1.)inletold_pensize=h.pensizein(* drawing function *)letf=(fun()->letr',g',b'=plgcol01inplscol01rgb;plcol01;ifline_width>(-1.)thenplwidthline_width;letc'=plgchr()|>fstinplschrmarker_size1.;ifline_style>0&&line_style<9thenpllstyline_style;pllinexy;ifmarker<>""then(letx',y'=_thinningx,_thinningyinplstringx'y'marker);(* restore original settings *)plschrc'1.;plwidthold_pensize;pllsty1;plscol01r'g'b';plcol01)in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];(* add legend item to page *)_add_legend_itempLINEline_stylecolormarkercolor0color;ifnoth.holdonthenoutputhletplot_fun?(h=_default_handle)?(spec=[])fab=letx=Owl_dense_matrix.D.linspaceab100inlety=Owl_dense_matrix.D.mapfxinplot~h~specxyletscatter?(h=_default_handle)?(spec=[])xy=letopenPlplotinletx=Owl_dense_matrix.D.to_arrayxinlety=Owl_dense_matrix.D.to_arrayyin_adjust_rangehxX;_adjust_rangehyY;(* prepare the closure *)letp=h.pages.(h.current_page)inletcolor=_get_rgbspecp.fgcolorinletr,g,b=colorinletmarker=_get_markerspec"•"inletmarker_size=_get_marker_sizespec4.in(* drawing function *)letf=(fun()->letr',g',b'=plgcol01inplscol01rgb;plcol01;letc'=plgchr()|>fstinplschrmarker_size1.;plstringxymarker;(* restore original settings *)plschrc'1.;plscol01r'g'b';plcol01)in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];(* add legend item to page *)_add_legend_itempSCATTER0colormarkercolor0color;ifnoth.holdonthenoutputhlethistogram?(h=_default_handle)?(spec=[])?(bin=10)x=letopenPlplotinletx=Owl_dense_matrix.D.to_arrayxin_adjust_rangehxX;letxmin,xmax=Owl_stats.minmaxxinletymin,ymax=0.,Owl_stats.(histogramxbin|>Array.mapfloat_of_int|>max)*.1.1in_adjust_rangeh[|xmin;xmax|]X;_adjust_rangeh[|ymin;ymax|]Y;(* prepare the closure *)letp=h.pages.(h.current_page)inletcolor=_get_rgbspecp.fgcolorinletr,g,b=colorin(* drawing function *)letf=(fun()->letr',g',b'=plgcol01inlet_=plscol01rgb;plcol01inplhistxxminxmaxbin[PL_HIST_DEFAULT;PL_HIST_NOSCALING;PL_HIST_NOEXPAND];(* restore original settings *)plscol01r'g'b';plcol01;)in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];(* add legend item to page *)_add_legend_itempBOX1color""color0color;ifnoth.holdonthenoutputhletsubplothij=let_,n=h.shapeinh.current_page<-(n*i+j)letstem?(h=_default_handle)?(spec=[])xy=letopenPlplotinletx=Owl_dense_matrix.D.to_arrayxinlety=Owl_dense_matrix.D.to_arrayyin_adjust_rangehxX;_adjust_rangehyY;(* prepare the closure *)letp=h.pages.(h.current_page)inletcolor=_get_rgbspecp.fgcolorinletr,g,b=colorinletmarker=_get_markerspec"#[0x2299]"inletmarker_size=_get_marker_sizespec4.inletline_style=_get_line_stylespec2inletline_width=_get_line_widthspec(-1.)inletold_pensize=h.pensizein(* drawing function *)letf=(fun()->letr',g',b'=plgcol01inplscol01rgb;plcol01;ifline_width>(-1.)thenplwidthline_width;letc'=plgchr()|>fstinplschrmarker_size1.;ifline_style>0&&line_style<9then(pllstyline_style;Owl_utils.Array.iter2(funx'y'->pljoinx'0.x'y')xy);ifnot(marker="")thenplstringxymarker;(* restore original settings *)plschrc'1.;plwidthold_pensize;pllsty1;plscol01r'g'b';plcol01)in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];(* add legend item to page *)_add_legend_itempLINEline_stylecolormarkercolor0color;ifnoth.holdonthenoutputhletautocorr?(h=_default_handle)?(spec=[])x=letz=Owl_dense_matrix.D.to_arrayxinletx'=Array.init(Array.lengthz)(funi->float_of_inti)inlety'=Array.mapi(funi_->Owl_stats.autocorrelation~lag:iz)x'inletx'=Owl_dense_matrix.D.of_arrays[|x'|]inlety'=Owl_dense_matrix.D.of_arrays[|y'|]inset_xlabelh"Lag";set_ylabelh"Autocorrelation";(* prepare the closure *)letp=h.pages.(h.current_page)inletr,g,b=_get_rgbspecp.fgcolorinletcolor=RGB(r,g,b)inletmarker=Marker(_get_markerspec"•")inletmarker_size=MarkerSize(_get_marker_sizespec4.)inletline_style=LineStyle(_get_line_stylespec1)inletline_width=LineWidth(_get_line_widthspec(-1.))inletspec=[color;marker;marker_size;line_style;line_width]in(* drawing function *)stem~h~specx'y'letdraw_line?(h=_default_handle)?(spec=[])x0y0x1y1=letopenPlplotinletx=[|x0;x1|]inlety=[|y0;y1|]in_adjust_rangehxX;_adjust_rangehyY;(* prepare the closure *)letp=h.pages.(h.current_page)inletcolor=_get_rgbspecp.fgcolorinletr,g,b=colorinletline_style=_get_line_stylespec1inletline_width=_get_line_widthspec(-1.)inletold_pensize=h.pensizein(* drawing function *)letf=(fun()->letr',g',b'=plgcol01inplscol01rgb;plcol01;ifline_width>(-1.)thenplwidthline_width;ifline_style>0&&line_style<9then(pllstyline_style;pljoinx0y0x1y1);(* restore original settings *)plwidthold_pensize;pllsty1;plscol01r'g'b';plcol01)in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];ifnoth.holdonthenoutputh(* TODO *)letplot_multi=Nonelet_draw_error_bar?(w=0.)xye=letopenPlplotinletw=w/.2.in(* draw vertical line *)letx'=[|x;x|]inlety'=[|y-.e;y+.e|]inpllinex'y';(* draw upper bar *)letx'=[|x-.w;x+.w|]inlety'=[|y+.e;y+.e|]inpllinex'y';(* draw lower line *)letx'=[|x-.w;x+.w|]inlety'=[|y-.e;y-.e|]inpllinex'y'leterror_bar?(h=_default_handle)?(spec=[])xye=letopenPlplotinletymin=Owl_dense_matrix.D.(min'(y-e))inletymax=Owl_dense_matrix.D.(max'(y+e))inletx=Owl_dense_matrix.D.to_arrayxinlety=Owl_dense_matrix.D.to_arrayyinlete=Owl_dense_matrix.D.to_arrayein_adjust_rangehxX;_adjust_rangeh[|ymin;ymax|]Y;(* prepare the closure *)letp=h.pages.(h.current_page)inletcolor=_get_rgbspecp.fgcolorinletr,g,b=colorinletline_style=_get_line_stylespec1inletline_width=_get_line_widthspec(-1.)inletold_pensize=h.pensizeinletw=leta,b=Owl_stats.minmaxxin(a-.b)*.0.02in(* drawing function *)letf=(fun()->letr',g',b'=plgcol01inplscol01rgb;plcol01;ifline_width>(-1.)thenplwidthline_width;pllstyline_style;Owl_utils.Array.iter3(funx0y0e0->_draw_error_bar~wx0y0e0)xye;(* restore original settings *)plwidthold_pensize;pllsty1;plscol01r'g'b';plcol01)in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];ifnoth.holdonthenoutputhlet_draw_whiskers_boxwxy=letopenPlplotinletymed,y1st,y3rd=Owl_stats.(mediany,first_quartiley,third_quartiley)inletw=w/.2.inletx'=[|x-.w;x-.w;x+.w;x+.w;x-.w|]inlety'=[|y1st;y3rd;y3rd;y1st;y1st|]inpllsty1;pllinex'y';letx'=[|x-.w;x+.w|]inlety'=[|ymed;ymed|]inpllsty1;pllinex'y';letymin,ymax=Owl_stats.minmaxyinletx'=[|x;x|]inlety'=[|ymin;y1st|]inpllsty1;pllinex'y';letx'=[|x;x|]inlety'=[|y3rd;ymax|]inpllsty1;pllinex'y'letboxplot?(h=_default_handle)?(spec=[])y=letopenPlplotinletm,_=Owl_dense_matrix.D.shapeyinletx=Array.initm(funi->float_of_inti+.1.)inletxmin,xmax=Owl_stats.minmaxxinletw=0.4inlety0=Owl_dense_matrix.D.to_arrayyinlety1=Owl_dense_matrix.D.to_arraysyin_adjust_rangeh[|xmin-.w;xmax+.w|]X;_adjust_rangeh~margin:0.1y0Y;(* prepare the closure *)letp=h.pages.(h.current_page)inletcolor=_get_rgbspecp.fgcolorinletr,g,b=colorin(* drawing function *)letf=(fun()->letr',g',b'=plgcol01inplscol01rgb;plcol01;Owl_utils.Array.iter2(funx'y'->_draw_whiskers_boxwx'y')xy1;(* restore original settings *)plscol01r'g'b';plcol01;pllsty1)in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];ifnoth.holdonthenoutputhlet_draw_barwx0y0=letopenPlplotinletx=[|x0-.w;x0-.w;x0+.w;x0+.w|]inlety=[|0.;y0;y0;0.|]inplfillxy;pllsty1;pllinexyletdraw_rect?(h=_default_handle)?(spec=[])x0y0x1y1=letopenPlplotinletx=[|x0;x0;x1;x1|]inlety=[|y1;y0;y0;y1|]in_adjust_rangehxX;_adjust_rangehyY;(* prepare the closure *)letp=h.pages.(h.current_page)inletcolor=_get_rgbspecp.fgcolorinletr,g,b=colorinletline_style=_get_line_stylespec1inletfill_pattern=_get_fill_patternspec0in(* drawing function *)letf=(fun()->letr',g',b'=plgcol01inplscol01rgb;plcol01;pllstyline_style;plpstyfill_pattern;plfillxy;(* restore original settings *)plscol01r'g'b';plcol01;pllsty1)in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];ifnoth.holdonthenoutputhletbar?(h=_default_handle)?(spec=[])y=letopenPlplotinletw=0.4inlety=Owl_dense_matrix.D.to_arrayyinletx=Array.mapi(funi_->float_of_inti+.1.)yinletxmin,xmax=Owl_stats.minmaxxin_adjust_rangeh[|xmin-.w;xmax+.w|]X;_adjust_rangehyY;(* prepare the closure *)letp=h.pages.(h.current_page)inletcolor=_get_rgbspecp.fgcolorinletr,g,b=colorinletline_style=_get_line_stylespec1inletfill_pattern=_get_fill_patternspec0in(* drawing function *)letf=(fun()->letr',g',b'=plgcol01inplscol01rgb;plcol01;pllstyline_style;plpstyfill_pattern;Owl_utils.Array.iter2(funx0y0->_draw_barwx0y0)xy;(* restore original settings *)plscol01r'g'b';plcol01;pllsty1)in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];(* add legend item to page *)_add_legend_itempBOXline_stylecolor""colorfill_patterncolor;ifnoth.holdonthenoutputhletarea?(h=_default_handle)?(spec=[])xy=letopenPlplotinletx=Owl_dense_matrix.D.to_arrayxinlety=Owl_dense_matrix.D.to_arrayyinletxmin,xmax=Owl_stats.minmaxxinletx=Array.(append(append[|xmin|]x)[|xmax|])inlety=Array.(append(append[|0.|]y)[|0.|])in_adjust_rangehxX;_adjust_rangehyY;(* prepare the closure *)letp=h.pages.(h.current_page)inletcolor=_get_rgbspecp.fgcolorinletr,g,b=colorinletline_style=_get_line_stylespec1inletfill_pattern=_get_fill_patternspec0in(* drawing function *)letf=(fun()->letr',g',b'=plgcol01inplscol01rgb;plcol01;pllstyline_style;pllinexy;plpstyfill_pattern;plfillxy;(* restore original settings *)plscol01r'g'b';plcol01;pllsty1)in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];(* add legend item to page *)_add_legend_itempBOXline_stylecolor""colorfill_patterncolor;ifnoth.holdonthenoutputhletdraw_polygon?(h=_default_handle)?(spec=[])xy=letopenPlplotinletx=Owl_dense_matrix.D.to_arrayxinlety=Owl_dense_matrix.D.to_arrayyin_adjust_rangehxX;_adjust_rangehyY;(* prepare the closure *)letp=h.pages.(h.current_page)inletcolor=_get_rgbspecp.fgcolorinletr,g,b=colorinletline_style=_get_line_stylespec1inletfill_pattern=_get_fill_patternspec0in(* drawing function *)letf=(fun()->letr',g',b'=plgcol01inplscol01rgb;plcol01;pllstyline_style;pllinexy;plpstyfill_pattern;plfillxy;(* restore original settings *)plscol01r'g'b';plcol01;pllsty1)in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];(* add legend item to page *)_add_legend_itempBOXline_stylecolor""colorfill_patterncolor;ifnoth.holdonthenoutputhlet_ecdf_interleavexi=letm=Array.lengthxinletn=2*minlety=Array.maken0.inArray.iteri(funjz->letk=2*j+iinifk<ntheny.(k)<-z;ifk<n-1theny.(k+1)<-z)x;yletecdf?(h=_default_handle)?(spec=[])x=letx0=Owl_dense_matrix.D.to_arrayxinletx,y=Owl_stats.ecdfx0inletx=_ecdf_interleavex0inlety=_ecdf_interleavey1inletn=Array.lengthxinletx=Owl_dense_matrix.D.of_arrayxn1inlety=Owl_dense_matrix.D.of_arrayyn1inplot~h~specxyletstairs?(h=_default_handle)?(spec=[])xy=letx=Owl_dense_matrix.D.to_arrayxinlety=Owl_dense_matrix.D.to_arrayyinletx=_ecdf_interleavex0inleta=y.(0)inlety=_ecdf_interleavey1inlet_=y.(0)<-ainletn=Array.lengthxinletx=Owl_dense_matrix.D.of_arrayxn1inlety=Owl_dense_matrix.D.of_arrayyn1inplot~h~specxyletdraw_circle?(h=_default_handle)?(spec=[])xyrr=letopenPlplotinletn=1000inlettheta=(2.*.Owl_const.pi)/.(float_of_intn)inletx'=Array.init(n+1)(funi->x+.Owl_maths.(sin(float_of_inti*.theta))*.rr)inlety'=Array.init(n+1)(funi->y+.Owl_maths.(cos(float_of_inti*.theta))*.rr)in_adjust_rangeh~margin:0.05x'X;_adjust_rangeh~margin:0.05y'Y;(* prepare the closure *)letp=h.pages.(h.current_page)inletcolor=_get_rgbspecp.fgcolorinletr,g,b=colorinletline_style=_get_line_stylespec1inletline_width=_get_line_widthspec(-1.)inletfill_pattern=_get_fill_patternspec0inletold_pensize=h.pensizein(* drawing function *)letf=(fun()->letr',g',b'=plgcol01inplscol01rgb;plcol01;ifline_width>(-1.)thenplwidthline_width;pllstyline_style;plpstyfill_pattern;plfillx'y';pllinex'y';(* restore original settings *)plscol01r'g'b';plcol01;plwidthold_pensize;pllsty1)in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];ifnoth.holdonthenoutputhlet_draw_arcfillnx=letopenPlplotinleta=2.*.Owl_const.piinlettheta=a/.ninleti=ref0.inArray.iter(funy->letc=n*.yinletx'=Array.init(int_of_floatc+1)(funj->Owl_maths.(sin((float_of_intj+.!i)*.theta)))inlety'=Array.init(int_of_floatc+1)(funj->Owl_maths.(cos((float_of_intj+.!i)*.theta)))inletx'=Array.(append[|0.|]x')inlety'=Array.(append[|0.|]y')inpllinex'y';(* generates a color theme *)letr',g',b'=plgcol01inletrgb=mod_float((!i+.1.)*.50.)256.|>int_of_floatinplscol01rgbrgbrgb;plcol01;plpsty3;plfillx'y';(* restore original settings *)plscol01r'g'b';plcol01;i:=!i+.c;)x(* TODO: improve the filling ... *)letpie?(h=_default_handle)?(spec=[])x=letopenPlplotin_adjust_rangeh~margin:0.1[|-1.;1.|]X;_adjust_rangeh~margin:0.1[|-1.;1.|]Y;letx=Owl_dense_matrix.D.to_arrayxinletx=Owl_stats.normlise_pdfxin(* prepare the closure *)letp=h.pages.(h.current_page)inletcolor=_get_rgbspecp.fgcolorinletr,g,b=colorinletfill=_get_fillspecfalseinletold_pensize=h.pensizein(* drawing function *)letf=(fun()->letr',g',b'=plgcol01inplscol01rgb;plcol01;plwidth1.;pllsty1;plpsty0;_draw_arcfill1000.x;(* restore original settings *)plscol01r'g'b';plcol01;plwidthold_pensize;pllsty1)in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];ifnoth.holdonthenoutputhletloglog?(h=_default_handle)?(spec=[])?xy=letopenPlplotinlety=Owl_dense_matrix.D.to_arrayyinletn=Array.lengthyinletx=matchxwith|Somemtx->Owl_dense_matrix.D.to_arraymtx(* The range is [1..n] instead of [0..(n-1)] *)|None->Owl_dense_matrix.D.linspace1.(float_of_intn)n|>Owl_dense_matrix.D.to_arrayinletaxis=_get_axisspecXYinletx,y=matchaxiswith|X->(Array.mapOwl_maths.log10x,y)|Y->(x,Array.mapOwl_maths.log10y)|_->(Array.mapOwl_maths.log10x,Array.mapOwl_maths.log10y)in_adjust_rangehxX;_adjust_rangehyY;letp=h.pages.(h.current_page)inlet_=matchaxiswith|X->p.xlogscale<-true|Y->p.ylogscale<-true|_->(p.xlogscale<-true;p.ylogscale<-true)in(* prepare the closure *)letcolor=_get_rgbspecp.fgcolorinletr,g,b=colorinletmarker=_get_markerspec""inletmarker_size=_get_marker_sizespec4.inletline_style=_get_line_stylespec1inletline_width=_get_line_widthspec(-1.)inletold_pensize=h.pensizein(* drawing function *)letf=(fun()->letr',g',b'=plgcol01inplscol01rgb;plcol01;ifline_width>(-1.)thenplwidthline_width;letc'=plgchr()|>fstinplschrmarker_size1.;ifline_style>0&&line_style<9thenpllstyline_style;pllinexy;ifmarker<>""then(letx',y'=_thinningx,_thinningyinplstringx'y'marker);(* restore original settings *)plschrc'1.;plwidthold_pensize;pllsty1;plscol01r'g'b';plcol01)in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];(* add legend item to page *)_add_legend_itempLINEline_stylecolormarkercolor0color;ifnoth.holdonthenoutputhletsemilogx?(h=_default_handle)?(spec=[])?xy=letspec=spec@[AxisX]inmatchxwith|Somearr->loglog~h~spec~x:arry|None->loglog~h~specyletsemilogy?(h=_default_handle)?(spec=[])?xy=letspec=spec@[AxisY]inmatchxwith|Somearr->loglog~h~spec~x:arry|None->loglog~h~specyletsurf?(h=_default_handle)?(spec=[])xyz=letopenPlplotinletx=Owl_dense_matrix.D.(rowx0|>to_array)inlety=Owl_dense_matrix.D.(coly0|>to_array)inletz=Owl_dense_matrix.D.transposezinletz0=Owl_dense_matrix.D.to_arrayszinletz1=Owl_dense_matrix.D.to_arrayzin_adjust_rangehxX;_adjust_rangehyY;_adjust_rangehz1Z;(* construct contour level *)letzmin,zmax=Owl_stats.minmaxz1inletclvl=Owl_dense_matrix.D.(linspacezminzmax10|>to_array)in(* prepare the closure *)letp=h.pages.(h.current_page)inp.is_3d<-true;p.altitude<-_get_altitudespecp.altitude;p.azimuth<-_get_azimuthspecp.azimuth;(* assemble the specifications *)letmag_color=_get_mag_colorspectrueinletcontour=_get_contourspecfalseinletcurtain=_get_curtainspecfalseinletfaceted=_get_facetedspecfalseinletopt=[PL_DIFFUSE]inletopt=opt@ifmag_colorthen[PL_MAG_COLOR]else[]inletopt=opt@ifcontourthen[PL_BASE_CONT;PL_SURF_CONT]else[]inletopt=opt@ifcurtainthen[PL_DRAW_SIDES]else[]inletopt=opt@iffacetedthen[PL_FACETED]else[]in(* drawing function *)letf=(fun()->plsurf3dxyz0optclvl;(* restore original settings, if any *))in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];ifnoth.holdonthenoutputhletplot3d=surfletmesh?(h=_default_handle)?(spec=[])xyz=letopenPlplotinletx=Owl_dense_matrix.D.(rowx0|>to_array)inlety=Owl_dense_matrix.D.(coly0|>to_array)inletz=Owl_dense_matrix.D.transposezinletz0=Owl_dense_matrix.D.to_arrayszinletz1=Owl_dense_matrix.D.to_arrayzin_adjust_rangehxX;_adjust_rangehyY;_adjust_rangehz1Z;(* construct contour level *)letzmin,zmax=Owl_stats.minmaxz1inletclvl=Owl_dense_matrix.D.(linspacezminzmax10|>to_array)in(* prepare the closure *)letp=h.pages.(h.current_page)inp.is_3d<-true;p.altitude<-_get_altitudespecp.altitude;p.azimuth<-_get_azimuthspecp.azimuth;letcolor=_get_rgbspecp.fgcolorinletr,g,b=colorin(* assemble the specifications *)letmag_color=_get_mag_colorspectrueinletcontour=_get_contourspecfalseinletcurtain=_get_curtainspecfalseinletopt=[PL_MESH]inletopt=opt@[_get_zlinespecPL_DRAW_LINEXY]inletopt=opt@ifmag_colorthen[PL_MAG_COLOR]else[]inletopt=opt@ifcontourthen[PL_BASE_CONT;PL_SURF_CONT]else[]inletopt=opt@ifcurtainthen[PL_DRAW_SIDES]else[]in(* drawing function *)letf=(fun()->(* only takes effect when NoMagColor is set *)letr',g',b'=plgcol01inplscol01rgb;plcol01;matchcontourwith|true->plmeshcxyz0optclvl|false->plmeshxyz0opt;(* restore original settings, if any *)plscol01r'g'b';plcol01)in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];ifnoth.holdonthenoutputhletheatmap?(h=_default_handle)xyz=letopenPlplotinletx=Owl_dense_matrix.D.(rowx0|>to_array)inlety=Owl_dense_matrix.D.(coly0|>to_array)inletz=Owl_dense_matrix.D.transposezinletz0=Owl_dense_matrix.D.to_arrayszinletz1=Owl_dense_matrix.D.to_arrayzin_adjust_rangehxX;_adjust_rangehyY;_adjust_rangehz1Z;(* construct contour level *)letxmin,xmax=Owl_stats.minmaxxinletymin,ymax=Owl_stats.minmaxyinletzmin,zmax=Owl_stats.minmaxz1inletclvl=Owl_dense_matrix.D.(linspacezminzmax10|>to_array)in(* prepare the closure *)letp=h.pages.(h.current_page)inletf=(fun()->plshadesz0xminxmaxyminymaxclvl1.001.0false(* restore original settings, if any *))in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];ifnoth.holdonthenoutputhletcontour?(h=_default_handle)xyz=letopenPlplotinletm,n=Owl_dense_matrix.D.shapezinletx0=Owl_dense_matrix.D.to_arraysxinletx1=Owl_dense_matrix.D.to_arrayxinlety0=Owl_dense_matrix.D.to_arraysyinlety1=Owl_dense_matrix.D.to_arrayyinletz0=Owl_dense_matrix.D.to_arrayszinletz1=Owl_dense_matrix.D.to_arrayzin_adjust_rangehx1X;_adjust_rangehy1Y;(* construct contour level *)letzmin,zmax=Owl_stats.minmaxz1inletclvl=Owl_dense_matrix.D.(linspacezminzmax10|>to_array)in(* prepare the closure *)letp=h.pages.(h.current_page)inletf=(fun()->plset_pltr(pltr2x0y0);plcontz01m1nclvl;plunset_pltr()(* restore original settings, if any *))in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];ifnoth.holdonthenoutputhlet_draw_extended_linex0y0x1y1lrud=(* Specify two points, draw a line between them, and extend on both ends with dash line *)letopenPlplotinletx0,y0,x1,y1=ifx0>x1thenx1,y1,x0,y0elsex0,y0,x1,y1inletyl=ifx0=x1thenuelsey0-.(y1-.y0)/.(x1-.x0)*.(x0-.l)inletyr=ifx0=x1thendelsey1+.(y1-.y0)/.(x1-.x0)*.(r-.x1)inletxl=ifx0=x1thenx0elselinletxr=ifx0=x1thenx0elserinpllsty1;pljoinx0y0x1y1;pllsty3;pljoinxlylx0y0;pllsty3;pljoinx1y1xryr;(* restore line style *)pllsty1letprobplot?(h=_default_handle)?(spec=[])?(dist=(Owl_stats.gaussian_ppf~mu:0.~sigma:1.))?(noref=false)x=(* TODO: show y-axis as probability instead of invcdf; Choose suitable
yticks for different distribution; support for censor data, frequency *)(* inputs *)letopenPlplotinletx=Owl_dense_matrix.D.to_arrayx|>Owl_stats.sort~inc:trueinlety=letn=Array.lengthxinletqth=Owl_dense_matrix.D.linspace((1.-.0.5)/.float_of_intn)((float_of_intn-.0.5)/.float_of_intn)ninletq=Owl_dense_matrix.D.mapdistqthinOwl_dense_matrix.D.to_arrayqin_adjust_rangehxX;_adjust_rangehyY;(* parameters to draw the reference line *)letp1y,p1x=(Owl_stats.first_quartiley,Owl_stats.first_quartilex)inletp3y,p3x=(Owl_stats.third_quartiley,Owl_stats.third_quartilex)inletleft,right=Owl_stats.minmaxxinletup,down=Owl_stats.minmaxyin(* prepare the closure *)letp=h.pages.(h.current_page)inletcolor=_get_rgbspecp.fgcolorinletr,g,b=colorinletmarker=_get_markerspec"#[0x002b]"inletmarker_size=_get_marker_sizespec4.in(* drawing function *)letf=(fun()->letr',g',b'=plgcol01inplscol01rgb;plcol01;letc'=plgchr()|>fstinplschrmarker_size1.;ifnotnorefthen_draw_extended_linep1xp1yp3xp3yleftrightupdown;plstringxymarker;(* restore original settings *)plschrc'1.;plscol01r'g'b';plcol01)in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];(* add legend item to page *)_add_legend_itempSCATTER0colormarkercolor0color;ifnoth.holdonthenoutputhletnormplot?(h=_default_handle)?(spec=[])?(sigma=1.)x=(* TODO: replace yticklabels, including unseen tick labels, with user-defined labels *)letdist=Owl_stats.gaussian_ppf~mu:0.~sigmainprobplot~h~spec~dist:distxletwblplot?(h=_default_handle)?(spec=[])?(lambda=1.)?(k=1.)x=(* TODO: logscale and logfit *)(* inputs *)letopenPlplotinletx=Owl_dense_matrix.D.to_arrayx|>Owl_stats.sort~inc:trueinletdist=Owl_stats.weibull_ppf~shape:k~scale:lambdainlety=letn=Array.lengthxinletqth=Owl_dense_matrix.D.linspace((1.-.0.5)/.float_of_intn)((float_of_intn-.0.5)/.float_of_intn)ninletq=Owl_dense_matrix.D.mapdistqthinOwl_dense_matrix.D.to_arrayqin_adjust_rangehxX;_adjust_rangehyY;(* parameters to draw the reference line *)letp1y,p1x=(Owl_stats.first_quartiley,Owl_stats.first_quartilex)inletp3y,p3x=(Owl_stats.third_quartiley,Owl_stats.third_quartilex)inletleft,right=Owl_stats.minmaxxinletup,down=Owl_stats.minmaxyin(* prepare the closure; note the change to log sacle *)letp=h.pages.(h.current_page)inletcolor=_get_rgbspecp.fgcolorinletr,g,b=colorinletmarker=_get_markerspec"#[0x002b]"inletmarker_size=_get_marker_sizespec4.in(* drawing function *)letf=(fun()->letr',g',b'=plgcol01inplscol01rgb;plcol01;letc'=plgchr()|>fstinplschrmarker_size1.;_draw_extended_linep1xp1yp3xp3yleftrightupdown;plstringxymarker;(* restore original settings *)plschrc'1.;plscol01r'g'b';plcol01)in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];(* add legend item to page *)_add_legend_itempSCATTER0colormarkercolor0color;ifnoth.holdonthenoutputhlet_ecdf_distabp=(* find the ecdf value of probability value p; (a, b) is the output of
Stats.ecdf *)letrec_find_recxlsti=matchlstwith|hd::tl->if(hd>x)theni-1else_find_recxtl(i+1)|_->(Array.lengthb)-1inletticks=Array.to_listbinleti=_find_recpticks1ina.(i)letqqplot?(h=_default_handle)?(spec=[])?(pd=Owl_stats.gaussian_ppf~mu:0.~sigma:1.)?xy=(* TODO: support matrix input; add support for `pvec` argument;
plot the larger data input on x-axis *)letopenPlplotinlety=Owl_dense_matrix.D.to_arrayy|>Owl_stats.sort~inc:trueinletn=Array.lengthyinletdist=matchxwith|Somearr->(* if the second argument is a vector *)letx=Owl_dense_matrix.D.to_arrayarrin(* The empirical CDF of it is used as dist. *)leta,b=Owl_stats.ecdfxin(funp->_ecdf_distabp)|None->pdinletqth=Owl_dense_matrix.D.linspace((1.-.0.5)/.float_of_intn)((float_of_intn-.0.5)/.float_of_intn)ninletq=Owl_dense_matrix.D.mapdistqthinletx=Owl_dense_matrix.D.to_arrayqin(* draw the figure *)_adjust_rangehxX;_adjust_rangehyY;(* parameters to draw the reference line *)letp1y,p1x=(Owl_stats.first_quartiley,Owl_stats.first_quartilex)inletp3y,p3x=(Owl_stats.third_quartiley,Owl_stats.third_quartilex)inletleft,right=Owl_stats.minmaxxinletup,down=Owl_stats.minmaxyin(* prepare the closure *)letp=h.pages.(h.current_page)inletcolor=_get_rgbspecp.fgcolorinletr,g,b=colorinletmarker=_get_markerspec"#[0x002b]"inletmarker_size=_get_marker_sizespec4.in(* drawing function *)letf=(fun()->letr',g',b'=plgcol01inplscol01rgb;plcol01;letc'=plgchr()|>fstinplschrmarker_size1.;_draw_extended_linep1xp1yp3xp3yleftrightupdown;plstringxymarker;(* restore original settings *)plschrc'1.;plscol01r'g'b';plcol01)in(* add closure as a layer *)p.plots<-Array.appendp.plots[|f|];(* add legend item to page *)_add_legend_itempSCATTER0colormarkercolor0color;ifnoth.holdonthenoutputh(* TODO *)letscatterhist=None(* other plots *)letimage?(h=_default_handle)x=letopenPlplotin(* rotate the matrix 90 degree clockwise to be shown correctly as image *)letx=Owl_dense_matrix.D.rotatex90in(* compute necessary parameters *)letwidth,height=Owl_dense_matrix.D.shapexinletnum_col=Owl_dense_matrix.D.max'xinletimg=Owl_dense_matrix.D.to_arraysxinletwidth=float_of_intwidthinletheight=float_of_intheightinletnum_col=int_of_floatnum_colin(* specify the boundary of imageplot *)letx=[|1.0;width|]inlety=[|1.0;height|]in_adjust_rangehxX;_adjust_rangehyY;(* keep the scale of original image instead of 4:3 *)h.page_size<-(int_of_floatwidth,int_of_floatheight);(* prepare the closure *)letp=h.pages.(h.current_page)inlet_=p.no_axes<-trueinletf=(fun()->(* set gray_cmap *)letr=[|0.0;1.0|]inletg=[|0.0;1.0|]inletb=[|0.0;1.0|]inletpos=[|0.0;1.0|]inplscmap1nnum_col;plscmap1ltrueposrgbNone;plimageimg1.0width1.0height0.00.01.0width1.0height;(* possibly need to restore original settings *))inp.plots<-Array.appendp.plots[|f|];ifnoth.holdonthenoutputhletspy?(h=_default_handle)?(spec=[])x=letxs=Owl_utils.Stack.make()inletys=Owl_utils.Stack.make()inletm,n=Owl_dense_matrix.D.shapexinfori=0tom-1doforj=0ton-1doleta=Owl_dense_matrix.D.getxijinifa<>0.then(Owl_utils.Stack.pushxs(float_of_inti);Owl_utils.Stack.pushys(float_of_intj);)done;done;letx=Owl_utils.Stack.to_arrayxsinlety=Owl_utils.Stack.to_arrayysinletx=Owl_dense_matrix.D.of_arrays[|x|]inlety=Owl_dense_matrix.D.of_arrays[|y|]inscatter~h~specxy(* ends here *)