Sei sulla pagina 1di 12

Myunderstandingofhowmplworks.

MPLhasthreelevels:

Aprocedurallevelatthetopgivesplottingfunctionslikeplot(),imshow(),etc.ThisAPIwas
takenessentiallywholesalefromMATLAB.Goodtofixthetoplevelatbeginning.

OOlevel,whereartiststhatdrawarerepresented,devsrecommendtoworkatthislevel,
worksjustaswellasattheprocedurallevel.Theseartistsdrawthemselveswiththelayer
describedbelow.

Thebackendlevelorthebottomhas(defines)simpledrawingcommandsthatactuallydothe
drawing.Thereareabunchofdifferentbackends.NoninteractivebackendsincludeAgg,
PDF,EPS,andSVG,whichwritethefiguresdirectlytofiles.InteractivebackendslikeGTKor
Qtalsomanagefigurewindowsinadditiontoprovidingdrawingcommands.Different
backendsperformratherdifferentlyandthedifferenceswillbemorepronouncedin3d
drawing.

Implementingabackendisrathersimpleasthedrawingcommandstobeimplementedare
simple,butthismakes3Dplottingdifficultbecausethebackendsjustputpoints,lines,
images,andtextonaplane,soallofthe3Dprojectionmustbedoneonelevelup,intheOO
code.ThereisnotechnicalreasonMPLdoesn'thaveaOpenGlbackendwecouldprobably
writeoneinadayortwo.Butitwouldbeawaste(alsoinclementsaidthatitwasnotexactly
whatwewanted)allitwoulddoisdrawlinesandpointsonthescreenthe3Dnessis
trappedatahigherlevel.

FromthemplthreadQtbackend:
http://sourceforge.net/p/matplotlib/mailman/message/5194374/
Thefirstplacetostartisinthefilematplotlib/backends/backend_template.py,whichserves
asatemplateforbackendwritersandgivessomeinstructions.Iwouldfollowthemodelof
oneofthe*Aggbackends,egTkAgg,GTKAgg,FLTKAggandWXAgg,whichuseAggto
rendertheimageandplaceitintheGUIcanvas.Thisisalotlessworkandyouautomatically
getthelatestmatplotlibfeaturesetforfree.ThebasicideaistouseaGUIindependent

imagelibrarythatcanthenbereusedacrossGUIs.

Thebackendshavetoimplementconcreteversionsofseveralinterfaceclasses:
RendererBase,GraphicsContextBase,FigureCanvasBase,FigureManagerBase,
NavigationToolbar2.IfyouopttouseAgg(orCairo)todothedrawingforyou,youcanleave
outRendererBaseandGraphicsContextBase,whicharethetwothatrequirethemostwork.
byJohnHunter

Agg=Gziparchive(551KB)
Readandaddviewsaboutuseofagg.
http://www.antigrain.com/doc/index.html

Cairo=1.4MB
ReadandaddviewsaboutuseofCairo.
http://cairographics.org/OpenGL/

//MatplotlibvsVispy(orvisvis):
Apparentlyevenvispypeopleareusingmplasvisvisisnotasgood(mplhasrichfeatureset
andnicerdocumentationIthink).

ResearchoncompilingMatplotlibforandroid:
Thishasalreadybeendonebeforeaccordingtoinclement,usefullinksIhavefoundsofar:
Mplonandroid
pythonintegratematplotlibintoandroidapp?StackOverflow
MyAndroidspeaksFortran..yourscantoo!
Howtoinstall3rdpartpythonmodulesforQPython?QPythonpythonforandroid
compilationThebestwaytointegratethirdpartylibraryinAndroidstudioStackOverflow
Numpyonandroid(thishasbeendonealready)
Issue260androidscriptingAddscipyandnumpymodulestostandardmodulesScripting
LayerforAndroidbringsscriptinglanguagestoAndroid.GoogleProjectHosting

NumPyPortGoogleGroups

ProposalDetailedDescription:

Implementation:
Plan:
Thefilesthataremostrelevanttobackend_writersare:
1)matplotlib/backends/backend_your_backend.py
2)matplotlib/backend_bases.py
3)matplotlib/backends/__init__.py
4)matplotlib/__init__.py:
5)matplotlib/_pylab_helpers.py

WiththeguidanceofprojectmentorsMatthewEinhorn(matham)andAlexander
Taylor(inclement)IhavecometothefollowingconclusionthattheMatplotlibbackendforkivy
willbemadeinfollowingthreesteps(itresultsinaprototyping+agiletypeofmodelof
softwareengineeringfollowingitsrulesmightbebeneficial):

1)
Writebackend_Kivyagg.pywhichwillusethelibraryAntiGrainGeometry(AGG)writtenin
industriallystandardC++(moreaboutaggintheresearchdocument).
Iwanttodothisbecauseofthefollowingreasons(the

source
ofthisisoldbutstillthepoint
stands):

a. Thebackendshavetoimplementconcreteversionsofthefollowingfiveinterface
classesRendererBase,GraphicsContextBase,FigureCanvasBase,
FigureManagerBaseandNavigationToolbar2.IfweletaggorCairodothedrawingfor
usthenwecanleaveoutcanleaveoutRendererBaseandGraphicsContextBase.
b. Thiswilltakelessertime(around15codingdays)andthereforewecannowtestifthis
worksoneachplatformsupportedbykivy(afterthekivywidgetismade).
2)
Writebackend_Kivy.pyusingkivysdrawingAPIandremovethedependencyonagg.
3)
Finallyifperformanceisunsatisfactory,mimicvispyandglumpy.Thislargelydependson
theviewsofthementorsandtheresultsoftestingondifferentdevicesafterstep2(thistime
testingshouldtakemuchlessertime).

Possibleproblems:
1)RestrictingMPLtoworkwithKivyclock:
Sincemplisbeingintegratedintokivy,andthereisaclockconflictherewewillhaveto
restrictmplsuchthatitworkswiththekivyclock.InourintegrationwewillsetKivyasthe
defaultmplbackend(setthebackendparameterinmatplotlibrcfile

Customizingmatplotlib
).
Elaborationoftheproblem:
Matplotlibhastwotypesofbackends:
1)UserInterfacebackendsorinteractivebackends.
2)Hardcopyornoninteractivebackendsbackendstomakeimagefiles.

AUIbackendpermitsbutdoesnotbyitselfrequireorensureplottingtothescreen.Thisis
determinedbytheinteractivemode(asonoroff).Ininteractivemodewhenyouuseapyplot
functionthecanvasisupdatedaftereachcall,(iftheOOlayerobjectsareusedthecanvasis

notupdateduntilobject.draw()iscalledasnocalltodraw_if_interactive()ispresentinobject
methods),wheninteractivemodeisoffabject.show()functionneedstobecalledforafigure
windowtoappear,afterthistheexecutionisblockedandthe
mplclockisstopped
.
Thishereistheproblem,wecanneverstoptheKivyclockbecausekivyiseventdrivenand
clockgeneratescertainevents.Insteadwhenshow()isusedwecandoanewEventloop()by
runTouchApp(widget=Figure,slave=False)andputthefigurewidgetinthisone,thiswaywe
achievempl's"don'tletthegraphdisappear"philosophyanditwon'taffectthenormal
executionofkivy(whichwillberunningbutnotvisible!).Toexitwecanhaveon_touch():
stopTouchApp().

2)Withperformance:
OpenGLisgoodasitdoesfasttransformationswithGPUbuttheMPLbackendstructure
wasn'tdesignedtopushmuchofthetransformationtothebackend.
TheissuewithanOpenGLbackendisthattheitreceivesalreadytransformeddata,andis
askedtorendereverythingateachframewhichisverymuchnonoptimal.
UploadthedataontheGPUatinitializationtime,andupdatesometransformationcoefficients
whentheuserpansandzoomsintothefigure(vectorgraphics!),thatshowaOpenGL
backendshouldwork.

Possiblesolutions
(toproblem2):
1)Thearchitectureof

Galry
ispreciselyarticulatedaroundthisconstraint.(Theauthorofgalry
isavispydev!).

2)JakeVanderplas'

mplexporter
.Theauthorhassome(veryold)interestingviewson
MatplotlibandtheFutureofVisualizationinPython
.

3)Whatthevispypeoplearedoing?
QuotinginclementTheydon'thaveanythingsignificantrightnow.Youmightbeinterestedin
thewaythey'regoingthroughIthinkthefocusisontakinganintermediaterepresentationof
afigureandworkingwiththat,ratherthancreatingamoredirectbackend.
Thatisagoodexplanationofwhattheyaredoing,thereasonisexactlywhatyouthink,i.e.
performance,theyarehackingtheOOlayerofmplandpushingthetransformationpartto
opengl.Ithinktheyaredrawinginspirationfrombothpoints1and2todothat.

Conclusion
mighthavetohacktheOOlayerofmplifwewanttodothetransformationsin
kivy.

ImplementationProcess:
Step1:
Followingthestepsgivenin

backend_template.py
thenaddKivyagg

here
tolistofinteractive
backends.Setthebackendparameterinmatplotlibrcfile
(asgivenhere
Customizing
matplotlib
)toKivy.Thiswillresultinavalidmplbackend,butnothingwouldbedrawn.Now
wecanproceedtostep2andseeourbackendstarttofunctionaswedefinethemethodsand
functionsinbacked_template(thiswillfacilitatewithtestingoffunctions).Iwilltestfunctions
thatcanbetestedindividuallyeverytimeIcompleteone.

Step2:

Thefollowingclassesinmatplotlib/backend_bases.pywillbeoverwrittenin
backend_Kivyagg.py:Abstractbaseclassesdefinetheprimitivesthatrenderersandgraphics
contextsmustimplementtoserveasamatplotlibbackend.

ClassFigureCanvasBase
TheabstractionlayerthatseparatestheClassmatplotlib.figure.Figurefromthebackend
specificdetailslikeauserinterfacedrawingarea.

ClassEvent
Thebaseclassforallofthematplotlibeventhandling.DerivedclassessuchasClass
KeyEventandClassMouseEventstorethemetadatalikekeysandbuttonspressed,xandy
locationsinpixelandClass~matplotlib.axes.Axescoordinates.

ClassShowBase
ThebaseclassfortheShowclassofeachinteractivebackendthe'show'callableisthenset
toShow.__call__,inheritedfromShowBase.
InclassShowBase,inthe__call__method,wehavethevariableblockwhosevaluewhennot
Noneisabooleanthatwilldecideweathertoblockornot,
here
wewillreplacethecallto
mainloopbyacalltohack_show()(willthinkofbettername)method,thismethodwillbe
definedasfollows,(allcodesnippetsaretargetedtoshowinteractionbetweenthetwo
libraries):
1.
2.
3.
4.
5.

defhack_show(Figure,*args):
runTouchApp(widget=Figure,slave=False)
#callrunTouchApp()withwidgetfigureasrootwidgetandslave=false
#givesautoeventdispatching,thisvaluemaygetchangedthen
#Thiswillcreateaneweventloop()inkivyandthusanewstack

6. #ofeventlisteners,callsafunctionthatwillupdate_canvaswhich
7. #willchangethecanvasinclassFigureManagerBase.
8. set_mpl_canvas(Figure)
9. #weswitchtorenderingonlythefigureinthewholewindowand
10. #thenon_touch():stopTouchApp()

1.
2.
3.
4.
5.
6.
7.

set_mpl_canvas(Figure,*args):
#betterput*args
#linkmyfiguretotheKivycanvas
self.canvas=FigureCanvasKivyAgg(self.f,master=master)
self.canvas._Kivycanvas.config(background="something",\

borderwidth=0,highlightthickness=0)
self.canvas.draw()

Aclosebuttonforfigureisneededhere.

Step3:
Thefollowingclassesinmatplotlib/backend_bases.pywillbeoverwrittenin
backend_Kivy.py(heretheKivydrawingapicomesintoaction):

ClassRendererBase
Anabstractbaseclasstohandledrawing/renderingoperations.

ClassGraphicsContextBase
Anabstractbaseclassthatprovidescolor,linestyles,andsoon.
Problem:
TransformationsarealreadydonebymplintheOOlayer!!
Applyappropriatesolutionfromtheabovementionedpossiblesolutions(mostprobablyoption
threewillbeused).

MakingtheFigurewidgetforKivy

MakingaKivywidgetcorrespondingtotheartist

figure
inmatplotlib.Thisseemseasilydoable
becauseoftheawesomekivywidgetstructure.Thisisthecodethatwouldbewrittenbya
usertoaccesswidgetfigure,withcodeIamtryingtoshowtheunderstandingIhaveofthe
controlflowandhowIthinkthestructurewillbelike:
1. fromkivy.appimportApp
2. fromkivy.uix.figureasFigure
3. importmatplotlib.pyplotasplt
4. importnumpyasnp
5. plt.ion()
6.
7.
8. defplot():
9. x=np.linspace(0,2,100)
10. plt.plot(x,x,label='linear')
11. plt.plot(x,x**2,label='quadratic')
12. plt.plot(x,x**3,label='cubic')
13. plt.xlabel('xlabel')
14. plt.ylabel('ylabel')
15. plt.title("SimplePlot")
16. plt.legend()
17.
18. classmpl_demoApp(App):
19. defbuild(self):
20.
returnFigure()
21.
#oncreationofnewfigurethecanvaswill
22.
#automaticallybesettothatofthenewestfigure
23.
#incaseofmultiplefiguresthecanvasselection
24.
#willbeasfollows
25.
f1=Figure()
26.
f2=Figure()
27.
#herethelatestfigureisf2socanvasissetto
28.
#f2,tosetitbacktof1
29.
update_canvas(f1)
30.
plot()#thiswillplotonfiguref1
31.
32.
33. mpl_demoApp().run()

Intheinitialize(__init__():)offigurewillbesomethinglikethis:


1.
2.
3.
4.

def__init__(self,*args):#forwidgetfigure
self.f=matplotlib.figure.Figure(figsize=(width,height),\

frameon=Boolean,dpi=something)
#creatingafigure,probablyshouldputsomedefaultsinsideof**kwargsforthose

5. #properties.

Thefollowingoutwouldbeproduced(theminimize&maximizebuttonsnearFigure1willnot
bethere):

Thesuggestedstyleofwritingmplcodeinakivyappwouldbetogroupthemplcodeasin
theaboveexample.Therearesevenbuttonshere,theclosebuttonwillbetheeighthbutton.
Interactivitywillbeachievedthroughthenormaleventbubblingprocedureusedinapps,i.e.
fromroottochild,andsoonuntiltheeventisconsumed,asdescribedinthekivy
documentation.

This
iswherethebehaviourofthesebuttonswillbeimplemented,itisthe
connectionofkivywidgettomplartistfigure.

Saveisimplementedusingaprint_xyz()method,registeredasthedefaulthandlerforagiven
filetypelike:
frommatplotlib.backend_basesimportregister_backend
register_backend('xyz','my_backend','XYZFileFormat')
...
plt.savefig("figure.xyz")
Thesegregationoffigurepropertieswillbedoneintotwocategories:
1)
Kivypropertiesofwidgetfigure,thesewillbelikeposition(x,y),size_x,size_y,size_hint_x,
size_hint_yandsoon(allthenontextandcanvaspropertiesofalabelwidget).
2)
Artistpropertiesofwidgetfigure,thesewillbethematplotlibpropertiesoffigureandsome
mayaltertheplot,allofthesepropertieswillneedtobecalledthroughfiguremanagerortheir
respectivegetterandsetterfunctions(initialization).

Toaccessalltheoptionscorrespondingtodifferentfigurewidgets:
1)
onemayusewidget.property()stylewhichincaseofmplpropertieswilltriggeracalltothe
widgetmanager.thiswaybothkivyandmplpropertiesofthewidgetcanbechanged.Aextra
setoffunctionswillbeneededheretopassvaluestothedifferentAPIsbutthestylewillbe
consistentforallfigureproperties.
2)
astyleconsistenttokivywidget_name(properties=set)butitwouldworkonlyforkivy
properties,ifthesamemethodwastobeusedforartistproperties,thenthereisachancethat
existingkivycodewillhavetobemodified(thesegregationofthesepropertieswillhavetobe
doneatsomeleveleg:createalistofallartist(widget)propertiesandchecklisttomodify
properties,butwewouldhavetomodifythislisteverytimeanewpropertyweretobe
added).

Whichevermethodlooksappropriateduringcoding,itwillbeimplemented.

THISISTHESOURCEOFTHISDOCUMENTANDITMAYBEUPDATED
//References:
matplotlib/MailingLists
matplotlib/backend_template.pyatmasterrastogiachyut/matplotlib
kivygarden/garden.graph
Boom!
ClientsideRenderinginMatplotlib,PartI:DefiningtheProblemBoom!
ClientsideRenderinginMatplotlib,PartII:TheLanguageBlenderBoom!
KivyGarden
FeatureRequest:A"pseudouser"classwithmethodsthat,e.g.,triggereventsordinarily
triggeredbyarealuserIssue#3019kivy/kivy
backendsMatplotlib1.4.3documentation
IRCChannelwxWidgets
Project.GSoC2015vispy/vispyWiki
ModernOpenGLtutorial(python)
mpld3/mplexporter
glumpy/spiral.pyatmasterglumpy/glumpy
Homematplotlib/matplotlibWiki
glumpy/glumpy/api/matplotlibatmasterglumpy/glumpy
Welcometovispysdocumentation!vispyv0.4docs
TheMPLplotmodulevispyv0.4docs

Potrebbero piacerti anche