plotcon nyc: plotlyjs.jl: interactive plotting in julia

52
: Interactive plotting in Julia Spencer Lyon November 18, 2016 NOTE: You are viewing a static export of an interactive web-based slide deck. Some items in the slides did not export properly to the pdf. To see a live version of the slides visit In [1]: PlotlyJS.jl http://spencerlyon.com/presentations/ using PlotlyJS Plotly javascript loaded. To load again call init_notebook(true)

Upload: plotly

Post on 08-Jan-2017

131 views

Category:

Data & Analytics


2 download

TRANSCRIPT

Page 1: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

:InteractiveplottinginJuliaSpencerLyon

November18,2016

NOTE:Youareviewingastaticexportofaninteractiveweb-basedslidedeck.Someitemsintheslidesdidnotexportproperlytothepdf.Toseealiveversionoftheslidesvisit

In [1]:

PlotlyJS.jl

http://spencerlyon.com/presentations/

using PlotlyJS

Plotlyjavascriptloaded.

Toloadagaincall

init_notebook(true)

Page 2: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

OutlineThanksBioBriefintrotoJulia

:plotly.jsinJuliaBasicsInteractivityConvenienceAPIStyles

PlotlyJS.jl

Page 3: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

Bio4thyearofeconomicsPhDprogramatNYUSternLiveinNYCwithwifeandthreekidsActiveinJuliacommunity,occasionalsightingsinSciPy/PyDataworldResearchinterestsare(inbroadterms)informationandbeliefs,internationalmacro,reinforcementlearning--allwithacomputationalslant

Page 4: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

WhatisJulia?

Forme:

Fastenough(intermsofmytimeandruntime)todoresearchcodeFuntoplaywith!

Juliaisahigh-level,high-performancedynamicprogramminglanguagefortechnicalcomputing,withsyntaxthatisfamiliartousersofothertechnicalcomputingenvironments.

Page 5: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

Coreconcept:Multipledispatch

Julia'scoreabstractionismultipledispatchFunctionsarespecializedbasedonthetypeofallarguments

WhenIcallf(x, y),whichfisrun?Bestunderstoodbyexample

Page 6: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

In [2]: f(x, y) = "Two arguments: $(x) and $(y)"f("hello", "plotcon")

Out[2]: "Two arguments: hello and plotcon"

Page 7: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

In [3]:

In [4]:

In [5]:

In [6]:

f(x::Number, y) = "First arg is a number ($(x)), second isn't ($(y))"

# still old methodf("hello", "plotcon")

# new methodf(2, "plotcon")

# Generics# also new method, but this time with floating point first argumentf(2.0, "plotcon")

Out[3]: f (generic function with 2 methods)

Out[4]: "Two arguments: hello and plotcon"

Out[5]: "First arg is a number (2), second isn't (plotcon)"

Out[6]: "First arg is a number (2.0), second isn't (plotcon)"

Page 8: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

In [7]:

In [8]:

In [9]:

# longer function syntaxfunction f(x::Number, y::Number) "Two numbers: ($(x), $(y))"end

# newest methodf(2.0, 2)

# unsigned 8 bit int and BigIntf(0x81, big(4))

Out[7]: f (generic function with 3 methods)

Out[8]: "Two numbers: (2.0, 2)"

Out[9]: "Two numbers: (129, 4)"

Page 9: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

What'sthepoint?

Ourffunctionisn'tusefulMultipledispatchenablesflexibilityandexpressivityWe'llleveragethisinPlotlyJS.jltomaketheAPIconvenient

Page 10: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

PlotlyJS.jlJuliawrapperforplotly.js:

CreatesplotlyplotsExposesplotly.jsAPIfunctionstoJulia

Twomaingoals:1. Makeitconvenienttoconstructandmanipulateplotlyvisualizations

fromJulia2. Provideinfrastructureforviewingplotsonmultiplefrontendsand

savingpublicationqualityplotlygraphicstofiles

Page 11: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

APIOverview

ThePlotlyJS.jlAPIhastwomainlayers:

1. Faithfulplotly.jslayer:makesitpossibletodoanythingplotly.jscan2. Convenience,"Julian"layer:WIPattempttomakesomethingsmorenaturalin

Julia

Page 12: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

Faithfulplotly.jsapilayer

plotly.jsvisualzationsaredescribedasaJSONobject:

Let'slookathowwecanbuildthesetracesandaLayoutinJulia

{ // Overall chart attributes "layout": { "title": "x²" }, "data": [ // JSON array of 'traces' { // Example trace "type": "scatter", "y": [1, 4.0, 9.0], "marker": { "symbol": "square" } } ]}

Page 13: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

ByHand

JSONisnaturallyrepresentedasJuliaDictExamplefromabove:

BuildingnestedDictsinJuliaisn'tconvenientNeedtospelloutDictNeedtoaddlotsofquotes(similartorawjson)Alsoneed=>toseparatekeys/values

Dict( "layout" => Dict( "title" => "x²" ), "data" => [ Dict( "type" => "scatter", "y" => [1, 4.0, 9.0], "marker" => Dict( "symbol" => "square" ) ) ])

Page 14: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

WithPlotlyJS.jl

PlotlyJS.jleasesthisburdenforJuliaprogrammers

In [10]: plot(scatter(y=[1.0, 4.0, 9.0], marker_symbol="square"), Layout(title="x²"))

Out[10]:

0 0.5 1 1.5 2

1

2

3

4

5

6

7

8

9

Page 15: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

Traces

Let'stakeacloserlookatbuildingtraceConstructtracesusingthetracetypeasafunctionandsettingkeywordargumentsExampletracefromabove:

In [11]:

Noticethesyntaxmarker_symbol.Thissetsanestedjsonatrribute{"marker": {"symbol": "square"}}Seethejson

In [12]:

my_trace = scatter(y=[1.0, 4.0, 9.0], marker_symbol="square")

print(json(my_trace, 2))

Out[11]: scatter with fields marker, type, and y

{ "y": [ 1.0, 4.0, 9.0 ], "type": "scatter", "marker": { "symbol": "square" }}

Page 16: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

MoreExamples

In [13]:

In [14]:

# nesting works at more than one leveltrace1 = scatter(y=rand(10), marker_color="red", marker_line_width=2.0)trace2 = contour(x=1:5, y=1:10, z=randn(5, 10))trace3 = bar(x=1:10, y=rand(1:10, 10), name="mybar")

print(json(trace1, 2))

Out[13]: bar with fields name, type, x, and y

{ "y": [ 0.8168546843804745, 0.1967457511182984, 0.5148182283741638, 0.31298671217983753, 0.10559144576552915, 0.6834355544280886, 0.7503355447535949, 0.33011457537607636, 0.05938681725632655, 0.858053689412962 ], "type": "scatter", "marker": { "line": { "width": 2.0 }, "color": "red" }}

Page 17: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

AlltracetypeshaveacorrespondingfunctionAlltraceattributesaresettable.Consult foranoverwhelminglycompletelist

apireference

Page 18: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

Layout

BuildalayoutbyconstructingaLayoutobject:

In [15]:

ThesameunderscoremagicappliesAlsonoticetheattrfunction.Thisallowsyoutocreategroupsofnestedattributes.foo=attr(x=1, y=2)produces{"foo": {"x": 1, "y": 2}}Itisanalternativetofoo_x=1, foo_y=2attrcanbeusedwhenbuildingtracesalso

layout = Layout(xaxis=attr(range=[0, 10], title="assets"), yaxis_title="consumption", title="??")

Out[15]: layout with fields margin, title, xaxis, and yaxis

Page 19: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

In [16]: print(json(layout, 2))

{ "yaxis": { "title": "consumption" }, "xaxis": { "range": [ 0, 10 ], "title": "assets" }, "title": "??", "margin": { "r": 50, "l": 50, "b": 50, "t": 60 }}

Page 20: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

Toactuallydisplayaplot,wetieoneormoretracestogetherwithalayoutbycallingtheplotfunction:

In [17]: plot(trace1, layout)

Out[17]:

0 2 4 6 8 10

0.1

0.2

0.3

0.4

0.5

0.6

0.7

0.8

0.9

??

assets

consumption

Page 21: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

In [18]: # layout optionalplot(trace2)

Out[18]:

Page 22: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

In [19]: # more than one traceplot([trace1, trace3], layout)

Out[19]:

Page 23: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

ConvenienceAPI

Theplotfunctionhasanumberofothermethodsthattrytomakeitabiteasierto

constructsimpleplots(remembermultipledispatch?:))

In [20]: methods(plot)

Out[20]: 13methodsforgenericfunctionplot:

plot{T<:Number,T2<:Number}(x::AbstractArray{T,1},y::AbstractArray{T2,2})at

plot{T<:Number,T2<:Number}(x::AbstractArray{T,1},y::AbstractArray{T2,2},l::PlotlyJS.Layout;style,kwargs...)at

plot{T<:Number,T2<:Number}(x::AbstractArray{T,2},y::AbstractArray{T2,2})at

plot{T<:Number,T2<:Number}(x::AbstractArray{T,2},y::AbstractArray{T2,2},l::PlotlyJS.Layout;style,kwargs...)at

plot{T<:Number,T2<:Number}(x::AbstractArray{T,N<:Any},

/Users/sglyon/.julia/v0.5/PlotlyJS/src/convenience_api.jl:31

/Users/sglyon/.julia/v0.5/PlotlyJS/src/convenience_api.jl:31

/Users/sglyon/.julia/v0.5/PlotlyJS/src/convenience_api.jl:40

/Users/sglyon/.julia/v0.5/PlotlyJS/src/convenience_api.jl:40

Page 24: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

Let'sseeafewoftheminaction

In [21]: x = linspace(-5, 5, 50)y1 = sin(x) y2 = cos(x)plot(x, y1)

Out[21]:

−4 −2 0 2 4

−1

−0.5

0

0.5

1

Page 25: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

In [22]: # x optional and set attributes with keywordsplot(y1, marker_color="red", mode="markers")

Out[22]:

0 10 20 30 40 50

−1

−0.5

0

0.5

1

Page 26: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

In [23]: # columns become tracesplot(x, [y1 y2], kind="bar")

Out[23]:

Page 27: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

In [24]: # can pass layoutplot(x, [y1 y2], Layout(title="My sinusoids"))

Out[24]:

−4 −2 0 2 4

−1

−0.5

0

0.5

1

Mysinusoids

trace0trace1

Page 28: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

In [25]: # can plot functionsplot([sin, _ -> cos(exp(sin(2*_)))], -6, 6, Layout(title="My sinusoids"), marker_symbol="square", mode="markers+lines", kind="bar")

Out[25]:

Page 29: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

Subplots

DeclarativeAPIsforsubplotscanbeverbosePlotlyJS.jltriestomakethiseasierforyouSupposeyouhavecreates4plotsusingplot:

Youcancombinethemintosubplotsusingfamiliar(h|v|hv)catsyntax:

p1 = plot(...)p2 = plot(...)p3 = plot(...)p4 = plot(...)

[p1 p2] # 1 row 2 cols[p1 p2 p3] # 1 row 3 cols[p1, p2] # 2 rows 1 col[p1 p2; p3 p4] # 2 rows 2 cols

Page 30: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

Example

In [26]: rand_plot(n) = plot(scatter(x=collect(1:n), y=randn(n)))p1, p2, p3, p4 = [rand_plot(i) for i in [10, 20, 30, 40]];

Page 31: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

In [27]: # 2 columns, 1 row[p1 p2]

Out[27]:

5 10

−1

−0.5

0

0.5

1

1.5

5 10 15 20−2

−1.5

−1

−0.5

0

0.5

1

1.5

2trace0trace1

Page 32: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

In [28]: # 3 columns, 1 row[p1 p2 p3]

Out[28]:

5 10

−1

−0.5

0

0.5

1

1.5

5 10 15 20−2

−1.5

−1

−0.5

0

0.5

1

1.5

2

10 20 30

−2

−1.5

−1

−0.5

0

0.5

1trace0trace1trace2

Page 33: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

In [29]: # two rows[p1, p2]

Out[29]:

2 4 6 8 10

−1

0

1

5 10 15 20−2

−1

0

1

2

trace0trace1

Page 34: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

In [30]: # two rows and columnsp = [p1 p2; p3 p4]

Out[30]:

5 10

−1

0

1

5 10 15 20−2

−1

0

1

2

10 20 30

−2

−1

0

1

10 20 30 40−2

−1

0

1

2

trace0trace1trace2trace3

Page 35: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

...underthehood

Wecaninspectthejsontoseewhatwe'vebeensavedfrom

In [31]: print(json(p))

{"layout":{"xaxis4":{"domain":[0.55,1.0],"anchor":"y4"},"xaxis3":{"domain":[0.0,0.45],"anchor":"y3"},"yaxis2":{"domain":[0.575,1.0],"anchor":"x2"},"yaxis1":{"domain":[0.575,1.0],"anchor":"x1"},"xaxis1":{"domain":[0.0,0.45],"anchor":"y1"},"margin":{"r":50,"l":50,"b":50,"t":60},"xaxis2":{"domain":[0.55,1.0],"anchor":"y2"},"yaxis4":{"domain":[5.551115123125783e-17,0.42500000000000004],"anchor":"x4"},"yaxis3":{"domain":[5.551115123125783e-17,0.42500000000000004],"anchor":"x3"}},"data":[{"yaxis":"y1","y":[0.4802673556774336,1.4948951444362697,-0.07045549774812956,0.7875701715665517,1.19154169230362,-0.019984297282311308,-1.2188104610632033,1.4889777636767583,0.1937548662633838,0.9467644161632363],"type":"scatter","xaxis":"x1","x":[1,2,3,4,5,6,7,8,9,10]},{"yaxis":"y2","y":[0.8116890547201712,0.026305587394362537,-1.9037677467854397,0.5179875294705465,1.132848386254002,-1.1211047904365008,-0.09732503991256072,-0.797064674081989,-0.5957822490328146,-1.5401700868810337,-0.8094006419764531,1.4733790412159211,1.8303960585896535,0.5451000885288673,-0.8508167149855682,0.5592069782568302,-0.5819292461464338,0.08366492698814007,-1.2171127224168015,-1.1731942880984414],"type":"scatter","xaxis":"x2","x":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]},{"yaxis":"y3","y":[0.44564426836146015,0.43568978674287906,-2.2957964903407775,-1.5588172083692364,-0.5175404777486905,-0.6879865409420531,-1.3614114948496532,-0.26860396772198347,-0.4550258510176642,-0.6661587413332551,-0.6568459806232246,-0.655160517941339,-1.0584839635045593,-0.9661978451654369,0.05588163077019386,0.4473040023028272,-0.4180878888519696,-0.670930203698033,-1.5680157591455446,-0.12061123763796747,0.422381416839956,-1.912905533601873,-0.7864305169890853,0.36283670860315104,1.1179292892139105,0.24868455953112426,0.8826378694420977,0.7852575028904395,-0.7092479652592288,-0.7193948586827139],"type":"scatter","xaxis":"x3","x":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]},{"yaxis":"y4","y":[-1.1744007569318526,-0.7773336011050302,1.4579909852349564,0.645916605678359,0.05423891204909586,-0.5428595063217369,0.7880545251999888,-0.14699104765892224,-0.3646094249332061,-0.4594704011787981,2.051735462555251,-0.10082715474940011,-1.1039826364944816,-0.6379899490941968,2.1124562929284965,1.553274330113308,-0.03180412490346881,0.5406670948650817,0.2738357386022979,-0.15275395057926666,-0.6982546882702967,-0.30727020052937565,0.214317134550011,-0.5067747133088952,0.009943218088108437,-1.3286282576286048,-0.7921663785646528,-1.920398068028969,-0.37936872456340026,0.04228943262867289,-0.9117834367846034,1.7365583749057234,-0.35923210966846647,-1.0974821703330992,-1.2833801773643732,-0.0005514726863847877,-0.9892149968313712,-0.1881051940753708,-0.0

Page 36: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

plotly.jsapifunctions

PlotlyJS.jlalsoexposesallplotly.jsAPIfunctionstopureJuliaSeelistLet'sseesomeexamples

here

Page 37: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

In [32]:

In [33]:

In [34]:

In [35]:

In [36]:

myplot = rand_plot(10)

restyle!(myplot, marker_color="ForestGreen")

relayout!(myplot, title="This is my title")

addtraces!(myplot, trace1)

prependtraces!(myplot, 1, x=[[0.1, 0.2, 0.3, 1]], y=[rand(4)])

Out[32]:

2 4 6 8 10

−1.5

−1

−0.5

0

0.5

1

1.5

Page 38: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

Interact.jl

WecanleverageInteract.jltoputhaveIPythonwidgetsinteractwithourplots

In [38]: using Interact

Page 39: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

In [39]: x = linspace(-4, 4, 70)p = plot(x, sin(x), Layout(xaxis_range=(-5, 5), yaxis_range=(-1.1, 1.1)))display(p)

colors = ["red", "green", "blue", "orange"]modes = ["markers", "lines", "markers+lines"]φs = linspace(-2, 2, 100)ωs = linspace(-π, π, 100)

@manipulate for c in colors, m in modes, φ in φs, ω in ωs y = sin.(ω*x + φ) restyle!(p, y=(y,), marker_color=c, mode=m)end

−4 −2 0 2 4

−1

−0.5

0

0.5

1

Page 40: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

Optgrowthexample

Page 41: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

FrontendsTheAPIpresentedabovecoversgoal1Goal2includesfrontendintegrationAkeyfeatureofPlotlyJS.jlisintegrationwithIJuliaandprovidingadedicatedGUIwindowjustforPlotlyJS.jlfigures

Page 42: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

Electron

Weuse toprovidean appforPlotlyJS.jlThisbuysusatleast2things:1. DedicatedGUIthatwecompletelycontrol2. Full2-waycommunicationwithjavascript

Javascriptinteropenables:LiveupdatesoftraceorlayoutattributesExtendingtracesoraddingnewtracestoadisplayedplotRawsvgoutputfromd3.jsforconversiontopdf,png,jpeg,eps,etc.More...

Demo

Blink.jl Electron

Page 43: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

IJulia

FirstclasssupportforjupyternotebooksStillhaveinteractivity,butcommunicationwithjavascriptgoesthroughanon-displayedelectronwindow...fornow("native"notebookcommunicationisclose)CanleveragetoolslikeInteract.jltotiearbitrarywidgetstoplotupdates

Page 44: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

Juno

CanhookintotheJunoPlotpaneinsideAtomBecauseAtomiselectron,thisfrontendsbehavesmuchliketheElectronone

Page 45: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

nteract

ReuseintegrationwithJupytertorenderplotsinnteract

Page 46: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

StylesPlotlyJS.jlversions>=0.4.0havesupportforplottingstyles.Thebestwaytothinkaboutstylesisthattheywillapplydefaultvaluesforattributes,onlyiftheattributeisnotalreadydefined.

Page 47: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

Styledefinitions

Stylesareinstacesofthistype:

immutable Style color_cycle::Vector layout::Layout global_trace::PlotlyAttribute trace::Dict{Symbol,PlotlyAttribute}end

Page 48: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

UsingSyles

TherearetwomainwaystouseaStyle:

Globalmode:calltheuse_style!(::Style)Plotbyplotmode:AllmethodsoftheplotandPlotfunctionsacceptakeywordargumentstyle::Stylethatsetsthestyleforthatplotonly.

In [43]: use_style!(:ggplot)simpleplot(;kw...) = plot([sin, cos], -6, 6; kw...)simpleplot()

Out[43]:

−0.5

0

0.5

1 sin

cos

Page 49: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

In [44]: simpleplot(style=style(:seaborn))

Out[44]:

−6 −4 −2 0 2 4 6

−1

−0.5

0

0.5

1sin

cos

Page 50: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

In [45]: simpleplot(style=style(:fivethirtyeight))

Out[45]:

−6 −4 −2 0 2 4 6

−1

−0.5

0

0.5

1 sincos

Page 51: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

In [46]: simpleplot(style=style(:tomorrow_night_eighties))

Out[46]:

−6 −4 −2 0 2 4 6

−1

−0.5

0

0.5

1 sin

cos

Page 52: PLOTCON NYC: PlotlyJS.jl: Interactive plotting in Julia

In [47]:

In [ ]:

simpleplot()

Out[47]:

−6 −4 −2 0 2 4 6

−1

−0.5

0

0.5

1 sin

cos