Merge 7264c01b85dccf1d5e4c45c3a4e1bb374f2c7968 into 8b2a83838894dc6d7f903a75e209362137e4d237

This commit is contained in:
Josef Heinen 2016-03-16 17:28:10 +00:00
commit ac5fb47503
12 changed files with 616 additions and 516 deletions

View File

@ -126,7 +126,8 @@ export
# recipes
PlotRecipe,
# EllipseRecipe,
spy
spy,
arcdiagram
# corrplot

View File

@ -11,7 +11,7 @@ const _3dTypes = [:path3d, :scatter3d, :surface, :wireframe]
const _allTypes = vcat([
:none, :line, :path, :steppre, :steppost, :sticks, :scatter,
:heatmap, :hexbin, :hist, :hist2d, :hist3d, :density, :bar, :hline, :vline, :ohlc,
:contour, :pie
:contour, :pie, :shape
], _3dTypes)
@compat const _typeAliases = Dict(
:n => :none,
@ -35,6 +35,9 @@ const _allTypes = vcat([
:line3d => :path3d,
:surf => :surface,
:wire => :wireframe,
:shapes => :shape,
:poly => :shape,
:polygon => :shape,
)
ishistlike(lt::Symbol) = lt in (:hist, :density)
@ -801,5 +804,3 @@ function getSeriesArgs(pkg::AbstractBackend, plotargs::Dict, kw, commandIndex::I
d
end

File diff suppressed because it is too large Load Diff

View File

@ -98,36 +98,36 @@ function gr_display(plt::Plot{GRBackend}, clear=true, update=true,
mwidth, mheight, width, height = GR.inqdspsize()
w, h = d[:size]
viewport = zeros(4)
vp = float(subplot)
if w > h
ratio = float(h) / w
msize = mwidth * w / width
GR.setwsviewport(0, msize, 0, msize * ratio)
GR.setwswindow(0, 1, 0, ratio)
viewport[1] = subplot[1] + 0.125 * (subplot[2] - subplot[1])
viewport[2] = subplot[1] + 0.95 * (subplot[2] - subplot[1])
viewport[3] = ratio * (subplot[3] + 0.125 * (subplot[4] - subplot[3]))
viewport[4] = ratio * (subplot[3] + 0.95 * (subplot[4] - subplot[3]))
vp[3] *= ratio
vp[4] *= ratio
else
ratio = float(w) / h
msize = mheight * h / height
GR.setwsviewport(0, msize * ratio, 0, msize)
GR.setwswindow(0, ratio, 0, 1)
viewport[1] = ratio * (subplot[1] + 0.125 * (subplot[2] - subplot[1]))
viewport[2] = ratio * (subplot[1] + 0.95 * (subplot[2] - subplot[1]))
viewport[3] = subplot[3] + 0.125 * (subplot[4] - subplot[3])
viewport[4] = subplot[3] + 0.95 * (subplot[4] - subplot[3])
vp[1] *= ratio
vp[2] *= ratio
end
viewport[1] = vp[1] + 0.125 * (vp[2] - vp[1])
viewport[2] = vp[1] + 0.95 * (vp[2] - vp[1])
viewport[3] = vp[3] + 0.125 * (vp[4] - vp[3])
if w > h
viewport[3] += (1 - (subplot[4] - subplot[3])^2) * 0.02
end
viewport[4] = vp[3] + 0.95 * (vp[4] - vp[3])
if haskey(d, :background_color)
GR.savestate()
GR.selntran(0)
GR.setfillintstyle(GR.INTSTYLE_SOLID)
GR.setfillcolorind(gr_getcolorind(d[:background_color]))
if w > h
GR.fillrect(subplot[1], subplot[2], ratio*subplot[3], ratio*subplot[4])
else
GR.fillrect(ratio*subplot[1], ratio*subplot[2], subplot[3], subplot[4])
end
GR.fillrect(vp[1], vp[2], vp[3], vp[4])
GR.selntran(1)
GR.restorestate()
c = getColor(d[:background_color])
@ -145,6 +145,7 @@ function gr_display(plt::Plot{GRBackend}, clear=true, update=true,
cmap = false
axes_2d = true
grid_flag = get(d, :grid, true)
outside_ticks = false
for axis = 1:2
xmin = ymin = typemax(Float64)
@ -176,12 +177,15 @@ function gr_display(plt::Plot{GRBackend}, clear=true, update=true,
xmin, xmax, ymin, ymax = 0, 1, 0, 1
x, y = p[:x], p[:y]
else
if p[:linetype] in [:contour, :surface]
if p[:linetype] in [:contour, :surface, :heatmap]
cmap = true
end
if p[:linetype] in [:surface, :wireframe, :path3d, :scatter3d]
axes_2d = false
end
if p[:linetype] == :heatmap
outside_ticks = true
end
x, y = p[:x], p[:y]
end
if p[:linetype] != :pie
@ -267,6 +271,9 @@ function gr_display(plt::Plot{GRBackend}, clear=true, update=true,
GR.setlinewidth(1)
GR.setlinecolorind(fg)
ticksize = 0.0075 * diag
if outside_ticks
ticksize = -ticksize
end
if grid_flag && fg == 1
GR.grid(xtick, ytick, 0, 0, majorx, majory)
end
@ -285,14 +292,14 @@ function gr_display(plt::Plot{GRBackend}, clear=true, update=true,
GR.savestate()
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_TOP)
GR.settextcolorind(fg)
GR.text(0.5 * (viewport[1] + viewport[2]), min(ratio, 1), d[:title])
GR.text(0.5 * (viewport[1] + viewport[2]), vp[4], d[:title])
GR.restorestate()
end
if get(d, :xlabel, "") != ""
GR.savestate()
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_BOTTOM)
GR.settextcolorind(fg)
GR.text(0.5 * (viewport[1] + viewport[2]), 0, d[:xlabel])
GR.text(0.5 * (viewport[1] + viewport[2]), vp[3], d[:xlabel])
GR.restorestate()
end
if get(d, :ylabel, "") != ""
@ -300,7 +307,7 @@ function gr_display(plt::Plot{GRBackend}, clear=true, update=true,
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_TOP)
GR.setcharup(-1, 0)
GR.settextcolorind(fg)
GR.text(0, 0.5 * (viewport[3] + viewport[4]), d[:ylabel])
GR.text(vp[1], 0.5 * (viewport[3] + viewport[4]), d[:ylabel])
GR.restorestate()
end
if get(d, :yrightlabel, "") != ""
@ -308,7 +315,7 @@ function gr_display(plt::Plot{GRBackend}, clear=true, update=true,
GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_TOP)
GR.setcharup(1, 0)
GR.settextcolorind(fg)
GR.text(1, 0.5 * (viewport[3] + viewport[4]), d[:yrightlabel])
GR.text(vp[2], 0.5 * (viewport[3] + viewport[4]), d[:yrightlabel])
GR.restorestate()
end
@ -497,6 +504,18 @@ function gr_display(plt::Plot{GRBackend}, clear=true, update=true,
viewport[3], viewport[4])
GR.colormap()
end
elseif p[:linetype] == :heatmap
x, y, z = p[:x], p[:y], p[:z].surf
zmin, zmax = GR.adjustrange(minimum(z), maximum(z))
GR.setspace(zmin, zmax, 0, 90)
GR.setcolormap(GR.COLORMAP_COOLWARM)
z = reshape(z, length(x) * length(y))
GR.surface(x, y, z, GR.OPTION_CELL_ARRAY)
if cmap
GR.setviewport(viewport[2] + 0.02, viewport[2] + 0.05,
viewport[3], viewport[4])
GR.colormap()
end
elseif p[:linetype] in [:path3d, :scatter3d]
x, y, z = p[:x], p[:y], p[:z]
zmin, zmax = GR.adjustrange(minimum(z), maximum(z))

View File

@ -6,26 +6,30 @@ 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 = 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")
# borrowed from https://github.com/plotly/plotly.py/blob/2594076e29584ede2d09f2aa40a8a195b3f3fc66/plotly/offline/offline.py#L64-L71 c/o @spencerlyon2
_js_script = """
<script type='text/javascript'>
define('plotly', function(require, exports, module) {
$(_js_code)
});
require(['plotly'], function(Plotly) {
window.Plotly = Plotly;
});
</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", """
<script type="text/javascript">
require=requirejs=define=undefined;
</script>
<script type="text/javascript">
$(open(readall, _js_path, "r"))
</script>
""")
# display("text/html", "<p>Plotly javascript loaded.</p>")
display("text/html", _js_script)
end
# end borrowing (thanks :)
###########################
# if isatom()
# import Atom
# Atom.@msg evaljs(_js_code)
# end
end
# TODO: other initialization
@ -436,15 +440,23 @@ function html_body(plt::Plot{PlotlyBackend}, style = nothing)
style = "width:$(w)px;height:$(h)px;"
end
uuid = Base.Random.uuid4()
"""
html = """
<div id=\"$(uuid)\" style=\"$(style)\"></div>
<script>
PLOT = document.getElementById('$(uuid)');
Plotly.plot(PLOT, $(get_series_json(plt)), $(get_plot_json(plt)));
</script>
"""
# @show html
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})
@ -479,7 +491,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})

View File

@ -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

View File

@ -81,7 +81,7 @@ supportedArgs(::GadflyBackend) = [
supportedAxes(::GadflyBackend) = [:auto, :left]
supportedTypes(::GadflyBackend) = [:none, :line, :path, :steppre, :steppost, :sticks,
:scatter, :hist2d, :hexbin, :hist, :bar,
:hline, :vline, :contour]
:hline, :vline, :contour, :shape]
supportedStyles(::GadflyBackend) = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
supportedMarkers(::GadflyBackend) = vcat(_allMarkers, Shape)
supportedScales(::GadflyBackend) = [:identity, :ln, :log2, :log10, :asinh, :sqrt]
@ -241,7 +241,7 @@ supportedArgs(::GRBackend) = [
supportedAxes(::GRBackend) = _allAxes
supportedTypes(::GRBackend) = [:none, :line, :path, :steppre, :steppost, :sticks,
:scatter, :hist2d, :hexbin, :hist, :density, :bar,
:hline, :vline, :contour, :path3d, :scatter3d, :surface,
:hline, :vline, :contour, :heatmap, :path3d, :scatter3d, :surface,
:wireframe, :ohlc, :pie]
supportedStyles(::GRBackend) = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot]
supportedMarkers(::GRBackend) = vcat(_allMarkers, Shape)
@ -770,4 +770,3 @@ supportedStyles(::PGFPlotsBackend) = [:auto, :solid] #, :dash, :dot, :dashdot, :
supportedMarkers(::PGFPlotsBackend) = [:none, :auto, :ellipse] #, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star5] #vcat(_allMarkers, Shape)
supportedScales(::PGFPlotsBackend) = [:identity] #, :log, :log2, :log10, :asinh, :sqrt]
subplotSupported(::PGFPlotsBackend) = false

View File

@ -3,6 +3,9 @@ immutable Shape
vertices::AVec
end
get_xs(shape::Shape) = Float64[v[1] for v in shape.vertices]
get_ys(shape::Shape) = Float64[v[2] for v in shape.vertices]
"get an array of tuples of points on a circle with radius `r`"
function partialcircle(start_θ, end_θ, n = 20, r=1)
@compat(Tuple{Float64,Float64})[(r*cos(u),r*sin(u)) for u in linspace(start_θ, end_θ, n)]

View File

@ -124,18 +124,23 @@ 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{T <: Union{GadflyBackend,ImmerseBackend,PyPlotBackend,GRBackend}}(Plot{T}, 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
# 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

View File

@ -444,6 +444,37 @@ function createKWargsList{T<:Real}(plt::AbstractPlot, x::AMat{T}, y::AMat{T}, zm
createKWargsList(plt, Any[x], Any[y]; d...) #kw..., z = surf, linetype = :contour)
end
# plotting arbitrary shapes/polygons
function createKWargsList(plt::AbstractPlot, shape::Shape; kw...)
x, y = unzip(shape.vertices)
createKWargsList(plt, x, y; linetype = :shape, kw...)
end
function shape_coords(shapes::AVec{Shape})
xs = map(get_xs, shapes)
ys = map(get_ys, shapes)
x, y = unzip(shapes[1].vertices)
for shape in shapes[2:end]
tmpx, tmpy = unzip(shape.vertices)
x = vcat(x, NaN, tmpx)
y = vcat(y, NaN, tmpy)
end
x, y
end
function createKWargsList(plt::AbstractPlot, shapes::AVec{Shape}; kw...)
x, y = shape_coords(shapes)
createKWargsList(plt, x, y; linetype = :shape, kw...)
end
function createKWargsList(plt::AbstractPlot, shapes::AMat{Shape}; kw...)
x, y = [], []
for j in 1:size(shapes, 2)
tmpx, tmpy = shape_coords(vec(shapes[:,j]))
push!(x, tmpx)
push!(y, tmpy)
end
createKWargsList(plt, x, y; linetype = :shape, kw...)
end
function createKWargsList(plt::AbstractPlot, surf::Surface; kw...)
createKWargsList(plt, 1:size(surf.surf,1), 1:size(surf.surf,2), convert(Matrix{Float64}, surf.surf); kw...)

View File

@ -137,3 +137,92 @@ function abline!(plt::Plot, a, b; kw...)
end
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

View File

@ -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