From c203bfe5ada12a577a78bb0fa4982dff8051f00d Mon Sep 17 00:00:00 2001 From: Thomas Breloff Date: Fri, 11 Mar 2016 14:59:11 -0500 Subject: [PATCH 1/8] working on atom/plotly --- src/backends/plotly.jl | 7 +++++-- src/backends/plotlyjs.jl | 3 ++- src/output.jl | 28 ++++++++++++++-------------- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index e7c24383..b8cccbd7 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -436,13 +436,15 @@ function html_body(plt::Plot{PlotlyBackend}, style = nothing) style = "width:$(w)px;height:$(h)px;" end uuid = Base.Random.uuid4() - """ + html = """
""" + # @show html + html end @@ -479,7 +481,8 @@ function Base.writemime(io::IO, ::MIME"image/png", plt::AbstractPlot{PlotlyBacke end function Base.writemime(io::IO, ::MIME"text/html", plt::AbstractPlot{PlotlyBackend}) - write(io, html_head(plt) * html_body(plt)) + write(io, html_head(plt) * html_body(plt)) + # write(io, html_body(plt)) end function Base.display(::PlotsDisplay, plt::AbstractPlot{PlotlyBackend}) diff --git a/src/backends/plotlyjs.jl b/src/backends/plotlyjs.jl index 1f12358f..ca972d98 100644 --- a/src/backends/plotlyjs.jl +++ b/src/backends/plotlyjs.jl @@ -44,6 +44,7 @@ function _add_series(::PlotlyJSBackend, plt::Plot; kw...) typ = pop!(pdict, :type) gt = PlotlyJS.GenericTrace(typ; pdict...) PlotlyJS.addtraces!(syncplot, gt) + # PlotlyJS.addtraces!(syncplot.plot, gt) push!(plt.seriesargs, d) plt @@ -73,6 +74,7 @@ function _update_plot(plt::Plot{PlotlyJSBackend}, d::Dict) syncplot = plt.o w,h = d[:size] PlotlyJS.relayout!(syncplot, pdict, width = w, height = h) + # PlotlyJS.relayout!(syncplot.plot, pdict, width = w, height = h) end @@ -125,4 +127,3 @@ end function Base.display(::PlotsDisplay, plt::Subplot{PlotlyJSBackend}) error() end - diff --git a/src/output.jl b/src/output.jl index aeb3adfb..4cc18bec 100644 --- a/src/output.jl +++ b/src/output.jl @@ -124,18 +124,18 @@ end # --------------------------------------------------------- function setup_atom() - # @require Atom begin - # @eval begin - # import Atom - # - # Atom.displaysize(::AbstractPlot) = (535, 379) - # Atom.displaytitle(::AbstractPlot) = "Plots.jl" - # - # Atom.@render Atom.PlotPane p::Plot begin - # x, y = Atom.@rpc Atom.plotsize() - # plot!(p, size=(x,y)) # changes the size of the Plots.Plot - # Atom.div(Dict(:style=>"background: white"), Atom.HTML(stringmime("text/html", p))) - # end - # end - # end + @require Atom begin + import Atom, Media + + # connects the render function + Media.media(Plot, Media.Plot) + + # Atom.displaysize(::AbstractPlot) = (535, 379) + # Atom.displaytitle(plt::AbstractPlot) = "Plots.jl (backend: $(backend(plt)))" + + # this is like "display"... sends an html div with the plot to the PlotPane + function Media.render(pane::Atom.PlotPane, plt::Plot) + Media.render(pane, Atom.div(Atom.d(), Atom.HTML(stringmime(MIME("text/html"), plt)))) + end + end end From c458a35670102c5e6c8794cfc244fb45c8491b16 Mon Sep 17 00:00:00 2001 From: Diego Javier Zea Date: Sun, 13 Mar 2016 16:27:35 -0300 Subject: [PATCH 2/8] arcdiagram --- src/Plots.jl | 3 +- src/recipes.jl | 95 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 94 insertions(+), 4 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index 7bf7304a..06ab4eef 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -126,7 +126,8 @@ export # recipes PlotRecipe, # EllipseRecipe, - spy + spy, + arcdiagram # corrplot diff --git a/src/recipes.jl b/src/recipes.jl index 639c2cf2..72645cdc 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -2,7 +2,7 @@ # TODO: there should be a distinction between an object that will manage a full plot, vs a component of a plot. # the PlotRecipe as currently implemented is more of a "custom component" -# a recipe should fully describe the plotting command(s) and call them, likewise for updating. +# a recipe should fully describe the plotting command(s) and call them, likewise for updating. # actually... maybe those should explicitly derive from AbstractPlot??? abstract PlotRecipe @@ -83,7 +83,7 @@ end # m = size(mat,2) # centers = Float64[mean(extrema(mat[:,i])) for i in 1:m] -# # might be a mistake? +# # might be a mistake? # @assert m <= 20 # @assert size(corrmat) == (m,m) @@ -136,4 +136,93 @@ function abline!(plt::Plot, a, b; kw...) plot!(plt, [extrema(plt)...], x -> b + a*x; kw...) end -abline!(args...; kw...) = abline!(current(), args...; kw...) \ No newline at end of file +abline!(args...; kw...) = abline!(current(), args...; kw...) + +# ------------------------------------------------- +# Arc Diagram + +curvecolor(value, min, max, grad) = getColorZ(grad, (value-min)/(max-min)) + +"Plots a clockwise arc, from source to destiny, colored by weight" +function arc!(source, destiny, weight, min, max, grad) + radius = (destiny - source) / 2 + arc = Plots.partialcircle(0, π, 30, radius) + x, y = Plots.unzip(arc) + plot!(x .+ radius .+ source, y, line = (curvecolor(weight, min, max, grad), 0.5, 2)) +end + +""" +`arcdiagram(source, destiny, weight[, grad])` + +Plots an arc diagram, form `source` to `destiny` (clockwise), using `weight` to determine the colors. +""" +function arcdiagram(source, destiny, weight, grad=ColorGradient(:bluesreds)) + + if length(source) == length(destiny) == length(weight) + + vertices = vcat(source, destiny) + + xmin, xmax = extrema(vertices) + plot(xlim=(xmin - 0.5, xmax + 0.5)) + + wmin,wmax = extrema(weight) + + for (i, j, value) in zip(source,destiny,weight) + arc!(i, j, value, wmin, wmax, grad) + end + + scatter!(vertices, zeros(length(vertices)), leg=false) + + else + + throw(ArgumentError("source, destiny and weight should have the same length")) + + end +end + +""" +`arcdiagram(mat[, grad])` + +Plots an arc diagram of a matrix, form rows to columns (clockwise), +using the values on the matrix as weights to determine the colors. +Doesn't show edges with value zero if the input is sparse. +For simmetric matrices, only the upper triangular values are used. +""" +function arcdiagram{T}(mat::AbstractArray{T,2}, grad=ColorGradient(:bluesreds)) + nrow, ncol = size(mat) # rows are sources and columns are destinies + + nosymmetric = !issym(mat) # plots only triu for symmetric matrices + nosparse = !issparse(mat) # doesn't plot zeros from a sparse matrix + + L = length(mat) + + source = Array(Int, L) + destiny = Array(Int, L) + weight = Array(T, L) + + idx = 1 + for i in 1:nrow, j in 1:ncol + value = mat[i, j] + if !isnan(value) && ( nosparse || value != zero(T) ) # TODO: deal with Nullable + + if i < j + source[idx] = i + destiny[idx] = j + weight[idx] = value + idx += 1 + elseif nosymmetric && (i > j) + source[idx] = i + destiny[idx] = j + weight[idx] = value + idx += 1 + end + + end + end + + resize!(source, idx-1) + resize!(destiny, idx-1) + resize!(weight, idx-1) + + arcdiagram(source, destiny, weight, grad) +end From 4d864d8cadab578183102608d592e2c38dee809c Mon Sep 17 00:00:00 2001 From: Thomas Breloff Date: Mon, 14 Mar 2016 16:58:01 -0400 Subject: [PATCH 3/8] working on atom integration --- src/backends/plotly.jl | 33 ++++++++++++++++++++++++--------- src/output.jl | 7 ++++++- src/utils.jl | 3 ++- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index b8cccbd7..583c2f8e 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -8,25 +8,34 @@ function _initialize_backend(::PlotlyBackend; kw...) ############################ # borrowed from https://github.com/spencerlyon2/Plotlyjs.jl/blob/master/src/display.jl - _js_path = joinpath(Pkg.dir("Plots"), "deps", "plotly-latest.min.js") + _js_path = Pkg.dir("Plots", "deps", "plotly-latest.min.js") + + _js_code = open(readall, _js_path, "r") + + _js_script = """ + + + """ # if we're in IJulia call setupnotebook to load js and css if isijulia() # the first script is some hack I needed to do in order for the notebook # to not complain about Plotly being undefined - display("text/html", """ - - - """) + display("text/html", _js_script) # display("text/html", "

Plotly javascript loaded.

") end # end borrowing (thanks :) ########################### + # if isatom() + # import Atom + # Atom.@msg evaljs(_js_code) + # end + end # TODO: other initialization end @@ -447,6 +456,12 @@ function html_body(plt::Plot{PlotlyBackend}, style = nothing) html end +function js_body(plt::Plot{PlotlyBackend}, uuid) + js = """ + PLOT = document.getElementById('$(uuid)'); + Plotly.plot(PLOT, $(get_series_json(plt)), $(get_plot_json(plt))); + """ +end function html_body(subplt::Subplot{PlotlyBackend}) diff --git a/src/output.jl b/src/output.jl index 4cc18bec..f3659a0d 100644 --- a/src/output.jl +++ b/src/output.jl @@ -128,7 +128,7 @@ function setup_atom() import Atom, Media # connects the render function - Media.media(Plot, Media.Plot) + Media.media{T <: Union{GadflyBackend,ImmerseBackend,PyPlotBackend,GRBackend}}(Plot{T}, Media.Plot) # Atom.displaysize(::AbstractPlot) = (535, 379) # Atom.displaytitle(plt::AbstractPlot) = "Plots.jl (backend: $(backend(plt)))" @@ -137,5 +137,10 @@ function setup_atom() function Media.render(pane::Atom.PlotPane, plt::Plot) Media.render(pane, Atom.div(Atom.d(), Atom.HTML(stringmime(MIME("text/html"), plt)))) end + + + # function Media.render(pane::Atom.PlotPane, plt::Plot{PlotlyBackend}) + # html = Media.render(pane, Atom.div(Atom.d(), Atom.HTML(stringmime(MIME("text/html"), plt)))) + # end end end diff --git a/src/utils.jl b/src/utils.jl index 3bdd2c2f..30ea6f99 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -198,6 +198,7 @@ function fakedata(sz...) end isijulia() = isdefined(Main, :IJulia) && Main.IJulia.inited +isatom() = isdefined(Main, :Atom) && Atom.isconnected() istuple(::Tuple) = true istuple(::Any) = false @@ -498,4 +499,4 @@ xmin(plt::Plot) = minimum([minimum(d[:x]) for d in plt.seriesargs]) xmax(plt::Plot) = maximum([maximum(d[:x]) for d in plt.seriesargs]) "Extrema of x-values in plot" -Base.extrema(plt::Plot) = (xmin(plt), xmax(plt)) \ No newline at end of file +Base.extrema(plt::Plot) = (xmin(plt), xmax(plt)) From 901115ed103a67b2160794c09e04d73babb26f5e Mon Sep 17 00:00:00 2001 From: Thomas Breloff Date: Tue, 15 Mar 2016 13:16:14 -0400 Subject: [PATCH 4/8] working on plotly/interact fix --- src/backends/plotly.jl | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 583c2f8e..fafbe44c 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -12,14 +12,26 @@ function _initialize_backend(::PlotlyBackend; kw...) _js_code = open(readall, _js_path, "r") + # _js_script = """ + # + # + # """ + + # borrowed from https://github.com/plotly/plotly.py/blob/2594076e29584ede2d09f2aa40a8a195b3f3fc66/plotly/offline/offline.py#L64-L71 c/o @spencerlyon2 _js_script = """ - - - """ + """ # if we're in IJulia call setupnotebook to load js and css if isijulia() From 16799d8b75fb1da93764258d1beeedd5f5a75340 Mon Sep 17 00:00:00 2001 From: Thomas Breloff Date: Wed, 16 Mar 2016 11:38:20 -0400 Subject: [PATCH 5/8] cleanup plotly --- src/backends/plotly.jl | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index fafbe44c..4fed40db 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -6,21 +6,9 @@ function _initialize_backend(::PlotlyBackend; kw...) import JSON JSON._print(io::IO, state::JSON.State, dt::Union{Date,DateTime}) = print(io, '"', dt, '"') - ############################ - # borrowed from https://github.com/spencerlyon2/Plotlyjs.jl/blob/master/src/display.jl _js_path = Pkg.dir("Plots", "deps", "plotly-latest.min.js") - _js_code = open(readall, _js_path, "r") - # _js_script = """ - # - # - # """ - # borrowed from https://github.com/plotly/plotly.py/blob/2594076e29584ede2d09f2aa40a8a195b3f3fc66/plotly/offline/offline.py#L64-L71 c/o @spencerlyon2 _js_script = """