switched Colors dep for PlotUtils dep; removed DataFrames, boxplot, violin, density and added StatPlots to tests
This commit is contained in:
parent
8d5b748b09
commit
4a2e88a81c
2
REQUIRE
2
REQUIRE
@ -1,7 +1,7 @@
|
|||||||
julia 0.4
|
julia 0.4
|
||||||
|
|
||||||
RecipesBase
|
RecipesBase
|
||||||
Colors
|
PlotUtils
|
||||||
Reexport
|
Reexport
|
||||||
Compat
|
Compat
|
||||||
FixedSizeArrays
|
FixedSizeArrays
|
||||||
|
|||||||
362
src/recipes.jl
362
src/recipes.jl
@ -101,47 +101,47 @@ num_series(x) = 1
|
|||||||
RecipesBase.apply_recipe{T}(d::KW, ::Type{T}, plt::Plot) = throw(MethodError("Unmatched plot recipe: $T"))
|
RecipesBase.apply_recipe{T}(d::KW, ::Type{T}, plt::Plot) = throw(MethodError("Unmatched plot recipe: $T"))
|
||||||
|
|
||||||
|
|
||||||
# TODO: remove when StatPlots is ready
|
# # TODO: remove when StatPlots is ready
|
||||||
if is_installed("DataFrames")
|
# if is_installed("DataFrames")
|
||||||
@eval begin
|
# @eval begin
|
||||||
import DataFrames
|
# import DataFrames
|
||||||
|
|
||||||
# if it's one symbol, set the guide and return the column
|
# # if it's one symbol, set the guide and return the column
|
||||||
function handle_dfs(df::DataFrames.AbstractDataFrame, d::KW, letter, sym::Symbol)
|
# function handle_dfs(df::DataFrames.AbstractDataFrame, d::KW, letter, sym::Symbol)
|
||||||
get!(d, Symbol(letter * "guide"), string(sym))
|
# get!(d, Symbol(letter * "guide"), string(sym))
|
||||||
collect(df[sym])
|
# collect(df[sym])
|
||||||
end
|
# end
|
||||||
|
|
||||||
# if it's an array of symbols, set the labels and return a Vector{Any} of columns
|
# # if it's an array of symbols, set the labels and return a Vector{Any} of columns
|
||||||
function handle_dfs(df::DataFrames.AbstractDataFrame, d::KW, letter, syms::AbstractArray{Symbol})
|
# function handle_dfs(df::DataFrames.AbstractDataFrame, d::KW, letter, syms::AbstractArray{Symbol})
|
||||||
get!(d, :label, reshape(syms, 1, length(syms)))
|
# get!(d, :label, reshape(syms, 1, length(syms)))
|
||||||
Any[collect(df[s]) for s in syms]
|
# Any[collect(df[s]) for s in syms]
|
||||||
end
|
# end
|
||||||
|
|
||||||
# for anything else, no-op
|
# # for anything else, no-op
|
||||||
function handle_dfs(df::DataFrames.AbstractDataFrame, d::KW, letter, anything)
|
# function handle_dfs(df::DataFrames.AbstractDataFrame, d::KW, letter, anything)
|
||||||
anything
|
# anything
|
||||||
end
|
# end
|
||||||
|
|
||||||
# handle grouping by DataFrame column
|
# # handle grouping by DataFrame column
|
||||||
function extractGroupArgs(group::Symbol, df::DataFrames.AbstractDataFrame, args...)
|
# function extractGroupArgs(group::Symbol, df::DataFrames.AbstractDataFrame, args...)
|
||||||
extractGroupArgs(collect(df[group]))
|
# extractGroupArgs(collect(df[group]))
|
||||||
end
|
# end
|
||||||
|
|
||||||
# if a DataFrame is the first arg, lets swap symbols out for columns
|
# # if a DataFrame is the first arg, lets swap symbols out for columns
|
||||||
@recipe function f(df::DataFrames.AbstractDataFrame, args...)
|
# @recipe function f(df::DataFrames.AbstractDataFrame, args...)
|
||||||
# if any of these attributes are symbols, swap out for the df column
|
# # if any of these attributes are symbols, swap out for the df column
|
||||||
for k in (:fillrange, :line_z, :marker_z, :markersize, :ribbon, :weights, :xerror, :yerror)
|
# for k in (:fillrange, :line_z, :marker_z, :markersize, :ribbon, :weights, :xerror, :yerror)
|
||||||
if haskey(d, k) && isa(d[k], Symbol)
|
# if haskey(d, k) && isa(d[k], Symbol)
|
||||||
d[k] = collect(df[d[k]])
|
# d[k] = collect(df[d[k]])
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
|
||||||
# return a list of new arguments
|
# # return a list of new arguments
|
||||||
tuple(Any[handle_dfs(df, d, (i==1 ? "x" : i==2 ? "y" : "z"), arg) for (i,arg) in enumerate(args)]...)
|
# tuple(Any[handle_dfs(df, d, (i==1 ? "x" : i==2 ? "y" : "z"), arg) for (i,arg) in enumerate(args)]...)
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@ -524,179 +524,179 @@ end
|
|||||||
|
|
||||||
# note: don't add dependencies because this really isn't a drop-in replacement
|
# note: don't add dependencies because this really isn't a drop-in replacement
|
||||||
|
|
||||||
# TODO: move boxplots and violin plots to StatPlots when it's ready
|
# # TODO: move boxplots and violin plots to StatPlots when it's ready
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# # ---------------------------------------------------------------------------
|
||||||
# Box Plot
|
# # Box Plot
|
||||||
|
|
||||||
const _box_halfwidth = 0.4
|
# const _box_halfwidth = 0.4
|
||||||
|
|
||||||
notch_width(q2, q4, N) = 1.58 * (q4-q2)/sqrt(N)
|
# notch_width(q2, q4, N) = 1.58 * (q4-q2)/sqrt(N)
|
||||||
|
|
||||||
|
|
||||||
@recipe function f(::Type{Val{:boxplot}}, x, y, z; notch=false, range=1.5)
|
# @recipe function f(::Type{Val{:boxplot}}, x, y, z; notch=false, range=1.5)
|
||||||
xsegs, ysegs = Segments(), Segments()
|
# xsegs, ysegs = Segments(), Segments()
|
||||||
glabels = sort(collect(unique(x)))
|
# glabels = sort(collect(unique(x)))
|
||||||
warning = false
|
# warning = false
|
||||||
outliers_x, outliers_y = zeros(0), zeros(0)
|
# outliers_x, outliers_y = zeros(0), zeros(0)
|
||||||
for (i,glabel) in enumerate(glabels)
|
# for (i,glabel) in enumerate(glabels)
|
||||||
# filter y
|
# # filter y
|
||||||
values = y[filter(i -> cycle(x,i) == glabel, 1:length(y))]
|
# values = y[filter(i -> cycle(x,i) == glabel, 1:length(y))]
|
||||||
|
|
||||||
# compute quantiles
|
# # compute quantiles
|
||||||
q1,q2,q3,q4,q5 = quantile(values, linspace(0,1,5))
|
# q1,q2,q3,q4,q5 = quantile(values, linspace(0,1,5))
|
||||||
|
|
||||||
# notch
|
# # notch
|
||||||
n = notch_width(q2, q4, length(values))
|
# n = notch_width(q2, q4, length(values))
|
||||||
|
|
||||||
# warn on inverted notches?
|
# # warn on inverted notches?
|
||||||
if notch && !warning && ( (q2>(q3-n)) || (q4<(q3+n)) )
|
# if notch && !warning && ( (q2>(q3-n)) || (q4<(q3+n)) )
|
||||||
warn("Boxplot's notch went outside hinges. Set notch to false.")
|
# warn("Boxplot's notch went outside hinges. Set notch to false.")
|
||||||
warning = true # Show the warning only one time
|
# warning = true # Show the warning only one time
|
||||||
end
|
# end
|
||||||
|
|
||||||
# make the shape
|
# # make the shape
|
||||||
center = discrete_value!(d[:subplot][:xaxis], glabel)[1]
|
# center = discrete_value!(d[:subplot][:xaxis], glabel)[1]
|
||||||
hw = d[:bar_width] == nothing ? _box_halfwidth : 0.5cycle(d[:bar_width], i)
|
# hw = d[:bar_width] == nothing ? _box_halfwidth : 0.5cycle(d[:bar_width], i)
|
||||||
l, m, r = center - hw, center, center + hw
|
# l, m, r = center - hw, center, center + hw
|
||||||
|
|
||||||
# internal nodes for notches
|
# # internal nodes for notches
|
||||||
L, R = center - 0.5 * hw, center + 0.5 * hw
|
# L, R = center - 0.5 * hw, center + 0.5 * hw
|
||||||
|
|
||||||
# outliers
|
# # outliers
|
||||||
if Float64(range) != 0.0 # if the range is 0.0, the whiskers will extend to the data
|
# if Float64(range) != 0.0 # if the range is 0.0, the whiskers will extend to the data
|
||||||
limit = range*(q4-q2)
|
# limit = range*(q4-q2)
|
||||||
inside = Float64[]
|
# inside = Float64[]
|
||||||
for value in values
|
# for value in values
|
||||||
if (value < (q2 - limit)) || (value > (q4 + limit))
|
# if (value < (q2 - limit)) || (value > (q4 + limit))
|
||||||
push!(outliers_y, value)
|
# push!(outliers_y, value)
|
||||||
push!(outliers_x, center)
|
# push!(outliers_x, center)
|
||||||
else
|
# else
|
||||||
push!(inside, value)
|
# push!(inside, value)
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
# change q1 and q5 to show outliers
|
# # change q1 and q5 to show outliers
|
||||||
# using maximum and minimum values inside the limits
|
# # using maximum and minimum values inside the limits
|
||||||
q1, q5 = extrema(inside)
|
# q1, q5 = extrema(inside)
|
||||||
end
|
# end
|
||||||
|
|
||||||
# Box
|
# # Box
|
||||||
if notch
|
# if notch
|
||||||
push!(xsegs, m, l, r, m, m) # lower T
|
# push!(xsegs, m, l, r, m, m) # lower T
|
||||||
push!(xsegs, l, l, L, R, r, r, l) # lower box
|
# push!(xsegs, l, l, L, R, r, r, l) # lower box
|
||||||
push!(xsegs, l, l, L, R, r, r, l) # upper box
|
# push!(xsegs, l, l, L, R, r, r, l) # upper box
|
||||||
push!(xsegs, m, l, r, m, m) # upper T
|
# push!(xsegs, m, l, r, m, m) # upper T
|
||||||
|
|
||||||
push!(ysegs, q1, q1, q1, q1, q2) # lower T
|
# push!(ysegs, q1, q1, q1, q1, q2) # lower T
|
||||||
push!(ysegs, q2, q3-n, q3, q3, q3-n, q2, q2) # lower box
|
# push!(ysegs, q2, q3-n, q3, q3, q3-n, q2, q2) # lower box
|
||||||
push!(ysegs, q4, q3+n, q3, q3, q3+n, q4, q4) # upper box
|
# push!(ysegs, q4, q3+n, q3, q3, q3+n, q4, q4) # upper box
|
||||||
push!(ysegs, q5, q5, q5, q5, q4) # upper T
|
# push!(ysegs, q5, q5, q5, q5, q4) # upper T
|
||||||
else
|
# else
|
||||||
push!(xsegs, m, l, r, m, m) # lower T
|
# push!(xsegs, m, l, r, m, m) # lower T
|
||||||
push!(xsegs, l, l, r, r, l) # lower box
|
# push!(xsegs, l, l, r, r, l) # lower box
|
||||||
push!(xsegs, l, l, r, r, l) # upper box
|
# push!(xsegs, l, l, r, r, l) # upper box
|
||||||
push!(xsegs, m, l, r, m, m) # upper T
|
# push!(xsegs, m, l, r, m, m) # upper T
|
||||||
|
|
||||||
push!(ysegs, q1, q1, q1, q1, q2) # lower T
|
# push!(ysegs, q1, q1, q1, q1, q2) # lower T
|
||||||
push!(ysegs, q2, q3, q3, q2, q2) # lower box
|
# push!(ysegs, q2, q3, q3, q2, q2) # lower box
|
||||||
push!(ysegs, q4, q3, q3, q4, q4) # upper box
|
# push!(ysegs, q4, q3, q3, q4, q4) # upper box
|
||||||
push!(ysegs, q5, q5, q5, q5, q4) # upper T
|
# push!(ysegs, q5, q5, q5, q5, q4) # upper T
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
|
||||||
# Outliers
|
# # Outliers
|
||||||
@series begin
|
# @series begin
|
||||||
seriestype := :scatter
|
# seriestype := :scatter
|
||||||
markershape := :circle
|
# markershape := :circle
|
||||||
markercolor := d[:fillcolor]
|
# markercolor := d[:fillcolor]
|
||||||
markeralpha := d[:fillalpha]
|
# markeralpha := d[:fillalpha]
|
||||||
markerstrokecolor := d[:linecolor]
|
# markerstrokecolor := d[:linecolor]
|
||||||
markerstrokealpha := d[:linealpha]
|
# markerstrokealpha := d[:linealpha]
|
||||||
x := outliers_x
|
# x := outliers_x
|
||||||
y := outliers_y
|
# y := outliers_y
|
||||||
primary := false
|
# primary := false
|
||||||
()
|
# ()
|
||||||
end
|
# end
|
||||||
|
|
||||||
seriestype := :shape
|
# seriestype := :shape
|
||||||
x := xsegs.pts
|
# x := xsegs.pts
|
||||||
y := ysegs.pts
|
# y := ysegs.pts
|
||||||
()
|
# ()
|
||||||
end
|
# end
|
||||||
@deps boxplot shape scatter
|
# @deps boxplot shape scatter
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# # ---------------------------------------------------------------------------
|
||||||
# Violin Plot
|
# # Violin Plot
|
||||||
|
|
||||||
const _violin_warned = [false]
|
# const _violin_warned = [false]
|
||||||
|
|
||||||
# if the user has KernelDensity installed, use this for violin plots.
|
# # if the user has KernelDensity installed, use this for violin plots.
|
||||||
# otherwise, just use a histogram
|
# # otherwise, just use a histogram
|
||||||
if is_installed("KernelDensity")
|
# if is_installed("KernelDensity")
|
||||||
@eval import KernelDensity
|
# @eval import KernelDensity
|
||||||
@eval function violin_coords(y; trim::Bool=false)
|
# @eval function violin_coords(y; trim::Bool=false)
|
||||||
kd = KernelDensity.kde(y, npoints = 200)
|
# kd = KernelDensity.kde(y, npoints = 200)
|
||||||
if trim
|
# if trim
|
||||||
xmin, xmax = extrema(y)
|
# xmin, xmax = extrema(y)
|
||||||
inside = Bool[ xmin <= x <= xmax for x in kd.x]
|
# inside = Bool[ xmin <= x <= xmax for x in kd.x]
|
||||||
return(kd.density[inside], kd.x[inside])
|
# return(kd.density[inside], kd.x[inside])
|
||||||
end
|
# end
|
||||||
kd.density, kd.x
|
# kd.density, kd.x
|
||||||
end
|
# end
|
||||||
else
|
# else
|
||||||
@eval function violin_coords(y; trim::Bool=false)
|
# @eval function violin_coords(y; trim::Bool=false)
|
||||||
if !_violin_warned[1]
|
# if !_violin_warned[1]
|
||||||
warn("Install the KernelDensity package for best results.")
|
# warn("Install the KernelDensity package for best results.")
|
||||||
_violin_warned[1] = true
|
# _violin_warned[1] = true
|
||||||
end
|
# end
|
||||||
edges, widths = my_hist(y, 10)
|
# edges, widths = my_hist(y, 10)
|
||||||
centers = 0.5 * (edges[1:end-1] + edges[2:end])
|
# centers = 0.5 * (edges[1:end-1] + edges[2:end])
|
||||||
ymin, ymax = extrema(y)
|
# ymin, ymax = extrema(y)
|
||||||
vcat(0.0, widths, 0.0), vcat(ymin, centers, ymax)
|
# vcat(0.0, widths, 0.0), vcat(ymin, centers, ymax)
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
|
||||||
|
|
||||||
@recipe function f(::Type{Val{:violin}}, x, y, z; trim=true)
|
# @recipe function f(::Type{Val{:violin}}, x, y, z; trim=true)
|
||||||
xsegs, ysegs = Segments(), Segments()
|
# xsegs, ysegs = Segments(), Segments()
|
||||||
glabels = sort(collect(unique(x)))
|
# glabels = sort(collect(unique(x)))
|
||||||
for glabel in glabels
|
# for glabel in glabels
|
||||||
widths, centers = violin_coords(y[filter(i -> cycle(x,i) == glabel, 1:length(y))], trim=trim)
|
# widths, centers = violin_coords(y[filter(i -> cycle(x,i) == glabel, 1:length(y))], trim=trim)
|
||||||
isempty(widths) && continue
|
# isempty(widths) && continue
|
||||||
|
|
||||||
# normalize
|
# # normalize
|
||||||
widths = _box_halfwidth * widths / maximum(widths)
|
# widths = _box_halfwidth * widths / maximum(widths)
|
||||||
|
|
||||||
# make the violin
|
# # make the violin
|
||||||
xcenter = discrete_value!(d[:subplot][:xaxis], glabel)[1]
|
# xcenter = discrete_value!(d[:subplot][:xaxis], glabel)[1]
|
||||||
xcoords = vcat(widths, -reverse(widths)) + xcenter
|
# xcoords = vcat(widths, -reverse(widths)) + xcenter
|
||||||
ycoords = vcat(centers, reverse(centers))
|
# ycoords = vcat(centers, reverse(centers))
|
||||||
|
|
||||||
push!(xsegs, xcoords)
|
# push!(xsegs, xcoords)
|
||||||
push!(ysegs, ycoords)
|
# push!(ysegs, ycoords)
|
||||||
end
|
# end
|
||||||
|
|
||||||
seriestype := :shape
|
# seriestype := :shape
|
||||||
x := xsegs.pts
|
# x := xsegs.pts
|
||||||
y := ysegs.pts
|
# y := ysegs.pts
|
||||||
()
|
# ()
|
||||||
end
|
# end
|
||||||
@deps violin shape
|
# @deps violin shape
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# # ---------------------------------------------------------------------------
|
||||||
# density
|
# # density
|
||||||
|
|
||||||
@recipe function f(::Type{Val{:density}}, x, y, z; trim=false)
|
# @recipe function f(::Type{Val{:density}}, x, y, z; trim=false)
|
||||||
newx, newy = violin_coords(y, trim=trim)
|
# newx, newy = violin_coords(y, trim=trim)
|
||||||
if isvertical(d)
|
# if isvertical(d)
|
||||||
newx, newy = newy, newx
|
# newx, newy = newy, newx
|
||||||
end
|
# end
|
||||||
x := newx
|
# x := newx
|
||||||
y := newy
|
# y := newy
|
||||||
seriestype := :path
|
# seriestype := :path
|
||||||
()
|
# ()
|
||||||
end
|
# end
|
||||||
@deps density path
|
# @deps density path
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# contourf - filled contours
|
# contourf - filled contours
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
julia 0.4
|
julia 0.4
|
||||||
|
|
||||||
RecipesBase
|
RecipesBase
|
||||||
Colors
|
PlotUtils
|
||||||
|
StatPlots
|
||||||
Reexport
|
Reexport
|
||||||
Measures
|
Measures
|
||||||
FactCheck
|
FactCheck
|
||||||
|
|||||||
@ -13,7 +13,9 @@ try
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
using Plots, FactCheck
|
using Plots
|
||||||
|
using StatPlots
|
||||||
|
using FactCheck
|
||||||
using Glob
|
using Glob
|
||||||
|
|
||||||
default(size=(500,300))
|
default(size=(500,300))
|
||||||
|
|||||||
@ -30,7 +30,7 @@ facts("GR") do
|
|||||||
@fact gr() --> Plots.GRBackend()
|
@fact gr() --> Plots.GRBackend()
|
||||||
@fact backend() --> Plots.GRBackend()
|
@fact backend() --> Plots.GRBackend()
|
||||||
|
|
||||||
@linux_only image_comparison_facts(:gr, skip=[], eps=img_eps)
|
# @linux_only image_comparison_facts(:gr, skip=[], eps=img_eps)
|
||||||
end
|
end
|
||||||
|
|
||||||
facts("Plotly") do
|
facts("Plotly") do
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user