Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support julia 1.0 #1189

Merged
merged 11 commits into from
Sep 14, 2018
15 changes: 5 additions & 10 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,16 @@ language: julia
os:
- linux
julia:
- 0.6
- 0.7
- 1.0
- nightly
matrix:
fast_finish: true
allow_failures:
- julia: nightly
notifications:
email: false
script:
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
- julia -e 'Pkg.clone(pwd()); Pkg.build("Gadfly");'
- julia -e 'Pkg.checkout("Compose")'
- julia --check-bounds=yes -e 'Pkg.test("Gadfly", coverage=true)'
before_script:
- julia -e 'using Pkg; Pkg.add(PackageSpec(name="Compose", rev="master"))'
after_success:
- julia -e 'cd(Pkg.dir("Gadfly")); Pkg.add("Coverage"); using Coverage; Codecov.submit(process_folder())'
- julia -e 'Pkg.checkout("Compose")'
- if [[ "$TRAVIS_JULIA_VERSION" == "0.6" ]]; then julia -e 'cd(Pkg.dir("Gadfly")); map(x->Pkg.add(strip(x)), readlines(open(joinpath("docs", "REQUIRE")))); include(joinpath("docs", "make.jl"))'; fi
- julia -e 'using Pkg; Pkg.add("Coverage"); using Coverage; Codecov.submit(process_folder())'
- julia -e 'using Pkg; foreach(x->Pkg.add(strip(x)), readlines(open(joinpath("docs", "REQUIRE")))); include(joinpath("docs", "make.jl"))'
6 changes: 3 additions & 3 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
julia 0.6.3
julia 0.7
CategoricalArrays # might be able to remove
Colors 0.3.4
Compat 0.18.0
Compose 0.5.2
Contour 0.1.1
CoupledFields
DataFrames 0.11.4
DataArrays
DataStructures
Distributions
DocStringExtensions
Expand All @@ -14,8 +14,8 @@ IterTools
JSON
KernelDensity
Loess
Measures
Showoff 0.0.3
StatsBase
Juno
IndirectArrays 0.4.2
Missings
2 changes: 1 addition & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ makedocs(

deploydocs(
repo = "github.com/GiovineItalia/Gadfly.jl.git",
julia = "0.6",
julia = "1.0",
osname = "linux",
deps = nothing,
make = nothing,
Expand Down
55 changes: 27 additions & 28 deletions src/Gadfly.jl
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
__precompile__()

module Gadfly

using Colors
using Compat
using Compose
using DataArrays
using DataFrames
using DataStructures
using JSON
using Showoff
using IndirectArrays
using CategoricalArrays
using Printf
using Base64

import IterTools
import IterTools: distinct, drop, chain
import Compose: draw, hstack, vstack, gridstack, isinstalled, parse_colorant
import Compose: draw, hstack, vstack, gridstack, parse_colorant
import Base: +, -, /, *,
copy, push!, start, next, done, show, getindex, cat,
copy, push!, show, getindex, cat,
show, isfinite, display
import Distributions: Distribution

Expand Down Expand Up @@ -59,7 +58,7 @@ function __init__()
end


const ColorOrNothing = Union{Colorant, (Void)}
const ColorOrNothing = Union{Colorant, (Nothing)}

element_aesthetics(::Any) = []
input_aesthetics(::Any) = []
Expand Down Expand Up @@ -132,11 +131,11 @@ set_default_plot_format(fmt::Symbol) = Compose.set_default_graphic_format(fmt)
# A plot has zero or more layers. Layers have a particular geometry and their
# own data, which is inherited from the plot if not given.
mutable struct Layer <: Element
data_source::Union{Void, MeltedData, AbstractArray, AbstractDataFrame}
data_source::Union{Nothing, MeltedData, AbstractArray, AbstractDataFrame}
mapping::Dict
statistics::Vector{StatisticElement}
geom::GeometryElement
theme::Union{Void, Theme}
theme::Union{Nothing, Theme}
order::Int
end
Layer() = Layer(nothing, Dict(), StatisticElement[], Geom.nil(), nothing, 0)
Expand All @@ -161,7 +160,7 @@ append!(ls, layer(y=[3,2,1], Geom.point))
plot(ls..., Guide.title("layer example"))
```
"""
function layer(data_source::Union{AbstractDataFrame, Void},
function layer(data_source::Union{AbstractDataFrame, Nothing},
elements::ElementOrFunction...; mapping...)
mapping = Dict{Symbol, Any}(mapping)
lyr = Layer()
Expand Down Expand Up @@ -211,11 +210,11 @@ add_plot_element!(lyrs::Vector{Layer}, arg::Theme) = [lyr.theme = arg for lyr in
# A full plot specification.
mutable struct Plot
layers::Vector{Layer}
data_source::Union{Void, MeltedData, AbstractArray, AbstractDataFrame}
data_source::Union{Nothing, MeltedData, AbstractArray, AbstractDataFrame}
data::Data
scales::Vector{ScaleElement}
statistics::Vector{StatisticElement}
coord::Union{Void, CoordinateElement}
coord::Union{Nothing, CoordinateElement}
guides::Vector{GuideElement}
theme::Theme
mapping::Dict
Expand Down Expand Up @@ -314,7 +313,7 @@ The old fashioned (pre-named arguments) version of plot. This version takes an
explicit mapping dictionary, mapping aesthetics symbols to expressions or
columns in the data frame.
"""
function plot(data_source::Union{Void, AbstractArray, AbstractDataFrame},
function plot(data_source::Union{Nothing, AbstractArray, AbstractDataFrame},
mapping::Dict, elements::ElementOrFunctionOrLayers...)
mapping = cleanmapping(mapping)
p = Plot()
Expand Down Expand Up @@ -381,7 +380,7 @@ function render_prepare(plot::Plot)

# Process layers, filling inheriting mappings or data from the Plot where
# they are missing.
datas = Array{Data}(length(plot.layers))
datas = Array{Data}(undef, length(plot.layers))
for (i, layer) in enumerate(plot.layers)
if layer.data_source === nothing && isempty(layer.mapping)
layer.data_source = plot.data_source
Expand Down Expand Up @@ -437,7 +436,7 @@ function render_prepare(plot::Plot)
end

# Add default statistics for geometries.
layer_stats = Array{Vector{StatisticElement}}(length(plot.layers))
layer_stats = Array{Vector{StatisticElement}}(undef, length(plot.layers))
for (i, layer) in enumerate(plot.layers)
layer_stats[i] = isempty(layer.statistics) ? ( isa(layer.geom, Geom.SubplotGeometry) ?
default_statistic(layer.geom) : [default_statistic(layer.geom)] ) : layer.statistics
Expand All @@ -456,9 +455,9 @@ function render_prepare(plot::Plot)
if mapreduce(x->in(x,layer_needed_aes),|,[:x,:xmax,:xmin]) &&
mapreduce(y->in(y,layer_needed_aes),|,[:y,:ymax,:ymin])
if !mapreduce(x->in(x,layer_defined_aes),|,[:x,:xmax,:xmin])
unshift!(layer_stats[i], Stat.x_enumerate)
pushfirst!(layer_stats[i], Stat.x_enumerate)
elseif !mapreduce(y->in(y,layer_defined_aes),|,[:y,:ymax,:ymin])
unshift!(layer_stats[i], Stat.y_enumerate)
pushfirst!(layer_stats[i], Stat.y_enumerate)
end
end
end
Expand Down Expand Up @@ -553,7 +552,7 @@ function render_prepare(plot::Plot)
(haskey(plot.mapping, var) || haskey(scales, var)) && continue

t = :categorical
for data in chain(datas, subplot_datas)
for data in Iterators.flatten((datas, subplot_datas))
val = getfield(data, var)
if val != nothing && val != :categorical
t = classify_data(val)
Expand Down Expand Up @@ -695,7 +694,7 @@ function render_prepare(plot::Plot)
keytypes = [Guide.ColorKey, Guide.ShapeKey]
supress_keys = false
for layer in plot.layers
if isa(layer.geom, Geom.SubplotGeometry) && any(haskey.(layer.geom.guides, keytypes))
if isa(layer.geom, Geom.SubplotGeometry) && any(haskey.((layer.geom.guides,), keytypes))
supress_keys = true
break
end
Expand All @@ -714,8 +713,8 @@ function render_prepare(plot::Plot)
end

# build arrays of scaled aesthetics for layers within subplots
layer_subplot_aess = Array{Vector{Aesthetics}}(length(plot.layers))
layer_subplot_datas = Array{Vector{Data}}(length(plot.layers))
layer_subplot_aess = Array{Vector{Aesthetics}}(undef, length(plot.layers))
layer_subplot_datas = Array{Vector{Data}}(undef, length(plot.layers))
j = 1
for (i, layer) in enumerate(plot.layers)
layer_subplot_aess[i] = Aesthetics[]
Expand Down Expand Up @@ -991,7 +990,7 @@ function default_mime()
end
end

import Base.REPL: REPLDisplay
import REPL: REPLDisplay

"""
display(p::Plot)
Expand All @@ -1001,19 +1000,19 @@ This function is handy when rendering by `plot` has been suppressed
with either trailing semi-colon or by calling it within a function.
"""
function display(d::REPLDisplay, p::Union{Plot,Compose.Context})
Copy link

@pfitzseb pfitzseb Sep 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't overload display(::REPLDisplay, ...) for things the REPL can't actually display. Instead define your own GadflyDisplay, define the appropriate display methods for those and pushdisplay it in your __init__.

The reason this is very unfortunate is that e.g. Juno can't display the plot (in a display(::JunoDisplay,...) call) and then fall back to display(::REPLDisplay, x), because that would show the plot again.

if mimewritable("text/html", p)
if showable("text/html", p)
display(d,"text/html", p)
return
elseif mimewritable("image/png", p)
elseif showable("image/png", p)
display(d,"image/png", p)
return
elseif mimewritable("application/pdf", p)
elseif showable("application/pdf", p)
display(d,"application/pdf", p)
return
elseif mimewritable("image/svg+xml", p)
elseif showable("image/svg+xml", p)
display(d,"image/svg+xml", p)
return
elseif mimewritable("application/postscript", p)
elseif showable("application/postscript", p)
display(d,"application/postscript", p)
return
end
Expand Down Expand Up @@ -1059,10 +1058,10 @@ function display(d::REPLDisplay, ::MIME"text/html", p::Union{Plot,Compose.Contex
</head>
<body style="margin:0">
<script charset="utf-8">
$(readstring(Compose.snapsvgjs))
$(read(Compose.snapsvgjs, String))
</script>
<script charset="utf-8">
$(readstring(gadflyjs))
$(read(gadflyjs, String))
</script>

$(plotsvg)
Expand Down
47 changes: 24 additions & 23 deletions src/aesthetics.jl
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
const NumericalOrCategoricalAesthetic =
Union{(Void), Vector, DataArray, IndirectArray}
Union{Nothing, Vector, Array, IndirectArray}
bjarthur marked this conversation as resolved.
Show resolved Hide resolved

const CategoricalAesthetic =
Union{(Void), IndirectArray}
Union{Nothing, IndirectArray}

const NumericalAesthetic =
Union{(Void), Matrix, Vector, DataArray}
Union{Nothing, Matrix, Vector, Array}
bjarthur marked this conversation as resolved.
Show resolved Hide resolved


@varset Aesthetics begin
x, Union{NumericalOrCategoricalAesthetic, Distribution}
y, Union{NumericalOrCategoricalAesthetic, Distribution}
z, Union{(Void), Function, NumericalAesthetic}
z, Union{Nothing, Function, NumericalAesthetic}
xend, NumericalAesthetic
yend, NumericalAesthetic

size, Union{CategoricalAesthetic,Vector,Void}
shape, Union{CategoricalAesthetic,Vector,Void}
color, Union{CategoricalAesthetic,Vector,Void}
linestyle, Union{CategoricalAesthetic,Vector,Void}
size, Union{CategoricalAesthetic,Vector,Nothing}
shape, Union{CategoricalAesthetic,Vector,Nothing}
color, Union{CategoricalAesthetic,Vector,Nothing}
linestyle, Union{CategoricalAesthetic,Vector,Nothing}

label, CategoricalAesthetic
group, CategoricalAesthetic
Expand Down Expand Up @@ -56,7 +56,7 @@ const NumericalAesthetic =
ytick, NumericalAesthetic
xgrid, NumericalAesthetic
ygrid, NumericalAesthetic
color_key_colors, Maybe(Associative)
color_key_colors, Maybe(AbstractDict)
color_key_title, Maybe(AbstractString)
color_key_continuous, Maybe(Bool)
color_function, Maybe(Function)
Expand Down Expand Up @@ -88,16 +88,17 @@ const NumericalAesthetic =
shape_label, Function, showoff

# pseudo-aesthetics
pad_categorical_x, Nullable{Bool}, Nullable{Bool}()
pad_categorical_y, Nullable{Bool}, Nullable{Bool}()
pad_categorical_x, Union{Missing,Bool}, missing
pad_categorical_y, Union{Missing,Bool}, missing
end


function show(io::IO, data::Aesthetics)
maxlen = 0
print(io, "Aesthetics(")
for name in fieldnames(Aesthetics)
if getfield(data, name) != nothing
val = getfield(data, name)
if !ismissing(val) && val != nothing
print(io, "\n ", string(name), "=")
show(io, getfield(data, name))
end
Expand Down Expand Up @@ -247,10 +248,10 @@ function concat(aess::Aesthetics...)
end


cat_aes_var!(a::(Void), b::(Void)) = a
cat_aes_var!(a::(Void), b::Union{Function,AbstractString}) = b
cat_aes_var!(a::(Void), b) = copy(b)
cat_aes_var!(a, b::(Void)) = a
cat_aes_var!(a::(Nothing), b::(Nothing)) = a
cat_aes_var!(a::(Nothing), b::Union{Function,AbstractString}) = b
cat_aes_var!(a::(Nothing), b) = copy(b)
cat_aes_var!(a, b::(Nothing)) = a
cat_aes_var!(a::Function, b::Function) = a === string || a == showoff ? b : a

function cat_aes_var!(a::Dict, b::Dict)
Expand All @@ -272,10 +273,10 @@ cat_aes_var!(a, b) = a

function cat_aes_var!(a::AbstractArray{T}, b::AbstractArray{U}) where {T, U}
V = promote_type(T, U)
if isa(a, DataArray) || isa(b, DataArray)
ab = DataArray(V, length(a) + length(b))
if isa(a, Array{Union{Missing,T}}) || isa(b, Array{Union{Missing,U}})
bjarthur marked this conversation as resolved.
Show resolved Hide resolved
ab = Array{Union{Missing,V}}(undef, length(a) + length(b))
else
ab = Array{V}(length(a) + length(b))
ab = Array{V}(undef, length(a) + length(b))
end
i = 1
for x in a
Expand Down Expand Up @@ -320,8 +321,8 @@ function by_xy_group(aes::T, xgroup, ygroup,
xrefs = xgroup === nothing ? [1] : xgroup
yrefs = ygroup === nothing ? [1] : ygroup

aes_grid = Array{T}(n, m)
staging = Array{AbstractArray}(n, m)
aes_grid = Array{T}(undef, n, m)
staging = Array{AbstractArray}(undef, n, m)
for i in 1:n, j in 1:m
aes_grid[i, j] = T()
end
Expand Down Expand Up @@ -370,7 +371,7 @@ function by_xy_group(aes::T, xgroup, ygroup,
if !applicable(convert, typeof(vals), staging[i, j])
T2 = eltype(vals)
if T2 <: Color T2 = Color end
da = DataArray(T2, length(staging[i, j]))
da = Array{Union{Missing,T2}}(undef, length(staging[i, j]))
copy!(da, staging[i, j])
setfield!(aes_grid[i, j], var, da)
else
Expand Down Expand Up @@ -404,7 +405,7 @@ function inherit!(a::Aesthetics, b::Aesthetics;
bval = getfield(b, field)
if field in clobber_set
setfield!(a, field, bval)
elseif aval === nothing || aval === string || aval == showoff
elseif aval === missing || aval === nothing || aval === string || aval == showoff
setfield!(a, field, bval)
elseif field == :xviewmin || field == :yviewmin
bval != nothing && (aval == nothing || aval > bval) && setfield!(a, field, bval)
Expand Down
2 changes: 1 addition & 1 deletion src/bincount.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ end
# numbins: number of bins
#
function bin!(bincounts::Vector, xs, x_min, binwidth, numbins)
bincounts[1:numbins] = 0
bincounts[1:numbins] .= 0
for x in xs
if !isconcrete(x)
continue
Expand Down
Loading