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

Time-to-first-plot improvements #1278

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
[compat]
CategoricalArrays = "0.5"
Colors = "0.9"
Compat = "2"
Compat = "2.1"
Compose = "0.7"
Contour = "0.5"
CoupledFields = "0.1"
Expand Down
51 changes: 25 additions & 26 deletions src/Gadfly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ function render_prepare(plot::Plot)

unscaled_aesthetics = setdiff(used_aesthetics, scaled_aesthetics)

_theme(plt, lyr) = lyr.theme == nothing ? plt.theme : lyr.theme
_theme(plt, lyr) = lyr.theme === nothing ? plt.theme : lyr.theme

# Add default scales for statistics.
layer_stats_with_theme = map(plot.layers, layer_stats) do l, stats
Expand Down Expand Up @@ -532,17 +532,17 @@ function render_prepare(plot::Plot)
in(var, mapped_aesthetics) || continue

var_data = getfield(plot.data, var)
if var_data == nothing
if var_data === nothing
for data in datas
var_layer_data = getfield(data, var)
if var_layer_data != nothing
if var_layer_data !== nothing
var_data = var_layer_data
break
end
end
end

var_data == nothing && continue
var_data === nothing && continue

t = classify_data(var_data)
if scale_exists(t, var)
Expand All @@ -560,7 +560,7 @@ function render_prepare(plot::Plot)
t = :categorical
for data in Iterators.flatten((datas, subplot_datas))
val = getfield(data, var)
if val != nothing && val != :categorical
if val !== nothing && val != :categorical
t = classify_data(val)
end
end
Expand Down Expand Up @@ -653,30 +653,33 @@ function render_prepare(plot::Plot)

# I. Scales
layer_aess = Scale.apply_scales(IterTools.distinct(values(scales)),
datas..., subplot_datas...)
vcat(datas, subplot_datas))

# set defaults for key titles
keyvars = [:color, :shape]
for (i, layer) in enumerate(plot.layers)
for kv in keyvars
fflag = (getfield(layer_aess[i], Symbol(kv,"_key_title")) == nothing) && haskey(layer.mapping, kv) && !isa(layer.mapping[kv], AbstractArray)
fflag = (getfield(layer_aess[i], Symbol(kv,"_key_title")) === nothing) &&
haskey(layer.mapping, kv) &&
!isa(layer.mapping[kv], AbstractArray)
fflag && setfield!(layer_aess[i], Symbol(kv,"_key_title"), string(layer.mapping[kv]))
end
end

for kv in keyvars
fflag = (getfield(layer_aess[1], Symbol(kv,"_key_title")) == nothing) && haskey(plot.mapping, kv) && !isa(plot.mapping[kv], AbstractArray)
fflag = (getfield(layer_aess[1], Symbol(kv,"_key_title")) === nothing) &&
haskey(plot.mapping, kv) && !isa(plot.mapping[kv], AbstractArray)
fflag && setfield!(layer_aess[1], Symbol(kv,"_key_title"), string(plot.mapping[kv]))
end

# Auto-update color scale if shape==color
catdatas = vcat(datas, subplot_datas)
shapev = getfield.(catdatas, :shape)
di = (shapev.!=nothing) .& (shapev.== getfield.(catdatas, :color))
di = @. (shapev !== nothing) & (shapev == getfield(catdatas, :color))

supress_colorkey = false
for (aes, data) in zip(layer_aess[di], catdatas[di])
aes.shape_key_title==nothing && (aes.shape_key_title=aes.color_key_title="Shape")
aes.shape_key_title === nothing && (aes.shape_key_title=aes.color_key_title="Shape")
colorf = scales[:color].f
scales[:color] = Scale.color_discrete(colorf, levels=scales[:shape].levels, order=scales[:shape].order)
Scale.apply_scale(scales[:color], [aes], Gadfly.Data(color=getfield(data,:color)) )
Expand All @@ -692,7 +695,7 @@ function render_prepare(plot::Plot)
end

# IIb. Plot-wise Statistics
plot_aes = concat(layer_aess...)
plot_aes = concat(layer_aess)
statistics = collect(statistics)
Stat.apply_statistics(statistics, scales, coord, plot_aes)

Expand All @@ -713,7 +716,7 @@ function render_prepare(plot::Plot)

if !supress_keys
for (KT, kv) in zip(keytypes, keyvars)
fflag = !all([getfield(aes, kv)==nothing for aes in [plot_aes, layer_aess...]])
fflag = !all([getfield(aes, kv) === nothing for aes in [plot_aes, layer_aess...]])
fflag && !in(KT, explicit_guide_types) && push!(guides, KT())
end
end
Expand Down Expand Up @@ -756,7 +759,7 @@ function render(plot::Plot)

ctx = pad_inner(root_context, plot.theme.plot_padding...)

if plot.theme.background_color != nothing
if plot.theme.background_color !== nothing
compose!(ctx, (context(order=-1000000),
fill(plot.theme.background_color),
stroke(nothing), rectangle()))
Expand Down Expand Up @@ -809,28 +812,24 @@ function render_prepared(plot::Plot,
# IV. Geometries
themes = Theme[layer.theme === nothing ? plot.theme : layer.theme
for layer in plot.layers]
zips = trim_zip(plot.layers, layer_aess,
layer_subplot_aess,
layer_subplot_datas,
themes)

compose!(plot_context,
[compose(context(order=layer.order), render(layer.geom, theme, aes,
subplot_aes, subplot_data,
scales))
for (layer, aes, subplot_aes, subplot_data, theme) in zips]...)
zips = trim_zip(plot.layers, layer_aess, layer_subplot_aess,
layer_subplot_datas, themes)
for (layer, aes, subplot_aes, subplot_data, theme) in zips
r = render(layer.geom, theme, aes, subplot_aes, subplot_data, scales)
compose!(plot_context, (context(order=layer.order), r))
end#for

# V. Guides
guide_contexts = Any[]
guide_contexts = Guide.PositionedGuide[]
for guide in guides
guide_context = render(guide, plot.theme, plot_aes, dynamic)
if guide_context != nothing
if guide_context !== nothing
append!(guide_contexts, guide_context)
end
end

tbl = Guide.layout_guides(plot_context, coord,
plot.theme, guide_contexts...)
plot.theme, guide_contexts)
if table_only
return tbl
end
Expand Down
43 changes: 19 additions & 24 deletions src/aesthetics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ function show(io::IO, data::Aesthetics)
print(io, "Aesthetics(")
for name in valid_aesthetics
val = getfield(data, name)
if !ismissing(val) && val != nothing
if !ismissing(val) && val !== nothing
print(io, "\n ", string(name), "=")
show(io, getfield(data, name))
end
Expand Down Expand Up @@ -172,7 +172,7 @@ function assert_aesthetics_undefined(who::AbstractString, aes::Aesthetics, vars:
end

function assert_aesthetics_equal_length(who::AbstractString, aes::Aesthetics, vars::Symbol...)
defined_vars = Compat.Iterators.filter(var -> !(getfield(aes, var) === nothing), vars)
defined_vars = Compat.Iterators.filter(var -> getfield(aes, var) !== nothing, vars)

if !isempty(defined_vars)
n = length(getfield(aes, first(defined_vars)))
Expand All @@ -198,7 +198,7 @@ end
#
function update!(a::Aesthetics, b::Aesthetics)
for name in valid_aesthetics
issomething(getfield(b, name)) && setfield(a, name, getfield(b, name))
getfield(b, name) !== nothing && setfield(a, name, getfield(b, name))
end
nothing
end
Expand Down Expand Up @@ -226,26 +226,21 @@ json(a::Aesthetics) = join([string(a, ":", json(getfield(a, var))) for var in ae
# Returns:
# A new Aesthetics instance with vectors concatenated.
#
function concat(aess::Aesthetics...)
function concat(aess)
cataes = Aesthetics()
for aes in aess
for var in valid_aesthetics
if var in [:xviewmin, :yviewmin]
mu, mv = getfield(cataes, var), getfield(aes, var)
setfield!(cataes, var,
mu === nothing ? mv :
mv == nothing ? mu :
min(mu, mv))
elseif var in [:xviewmax, :yviewmax]
mu, mv = getfield(cataes, var), getfield(aes, var)
setfield!(cataes, var,
mu === nothing ? mv :
mv == nothing ? mu :
max(mu, mv))
mu, mv = getfield(cataes, var), getfield(aes, var)
isviewmin = var in (:xviewmin, :yviewmin)
isviewmax = var in (:xviewmax, :yviewmax)
mumv = if isviewmin
mu === nothing ? mv : mv === nothing ? mu : min(mu, mv)
elseif isviewmax
mu === nothing ? mv : mv === nothing ? mu : max(mu, mv)
else
setfield!(cataes, var,
cat_aes_var!(getfield(cataes, var), getfield(aes, var)))
end
cat_aes_var!(mu, mv)
end#if
setfield!(cataes, var, mumv)
end
end
cataes
Expand Down Expand Up @@ -405,12 +400,12 @@ function inherit!(a::Aesthetics, b::Aesthetics;
bval = getfield(b, field)
if field in clobber_set
setfield!(a, field, bval)
elseif aval === missing || 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)
elseif field == :xviewmax || field == :yviewmax
bval != nothing && (aval == nothing || aval < bval) && setfield!(a, field, bval)
elseif field in (:xviewmin, :yviewmin) && bval !== nothing
(aval === nothing || aval > bval) && setfield!(a, field, bval)
elseif field in (:xviewmax, :yviewmax) && bval !== nothing
(aval === nothing || aval < bval) && setfield!(a, field, bval)
elseif typeof(aval) <: Dict && typeof(bval) <: Dict
merge!(aval, getfield(b, field))
end
Expand Down
12 changes: 6 additions & 6 deletions src/coord.jl
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ function apply_coordinate(coord::Cartesian, aess::Vector{Gadfly.Aesthetics},

xmin = xmax = first_concrete_aesthetic_value(aess, coord.xvars)

if xmin != nothing
if xmin !== nothing
for var in coord.xvars
for aes in aess
vals = getfield(aes, var)
Expand All @@ -169,7 +169,7 @@ function apply_coordinate(coord::Cartesian, aess::Vector{Gadfly.Aesthetics},
end

ymin = ymax = first_concrete_aesthetic_value(aess, coord.yvars)
if ymin != nothing
if ymin !== nothing
for var in coord.yvars
for aes in aess
vals = getfield(aes, var)
Expand All @@ -196,19 +196,19 @@ function apply_coordinate(coord::Cartesian, aess::Vector{Gadfly.Aesthetics},

# viewmin/max that is set explicitly should override min/max
for aes in aess
if aes.xviewmin != nothing
if aes.xviewmin !== nothing
xviewmin = xviewmin === nothing ? aes.xviewmin : min(xviewmin, aes.xviewmin)
end

if aes.xviewmax != nothing
if aes.xviewmax !== nothing
xviewmax = xviewmax === nothing ? aes.xviewmax : max(xviewmax, aes.xviewmax)
end

if aes.yviewmin != nothing
if aes.yviewmin !== nothing
yviewmin = yviewmin === nothing ? aes.yviewmin : min(yviewmin, aes.yviewmin)
end

if aes.yviewmax != nothing
if aes.yviewmax !== nothing
yviewmax = yviewmax === nothing ? aes.yviewmax : max(yviewmax, aes.yviewmax)
end
end
Expand Down
4 changes: 2 additions & 2 deletions src/data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function chain(ds::Data...)
chained_data = Data()
for name in data_fields
vs = Any[getfield(d, name) for d in ds]
vs = Any[v for v in filter(issomething, vs)]
vs = Any[v for v in filter(!isnothing, vs)]
if isempty(vs)
setfield!(chained_data, name, nothing)
else
Expand All @@ -78,7 +78,7 @@ function show(io::IO, data::Data)
maxlen = 0
print(io, "Data(")
for name in data_fields
if getfield(data, name) != nothing
if getfield(data, name) !== nothing
print(io, "\n ", string(name), "=")
show(io, getfield(data, name))
end
Expand Down
6 changes: 3 additions & 3 deletions src/dataframes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function meltdata(U::AbstractDataFrame, colgroups_::Vector{Col.GroupedColumn})
vm = um
grouped_columns = Set{Symbol}()
for colgroup in colgroups
if colgroup.columns===nothing # null => group all columns
if colgroup.columns === nothing # null => group all columns
vm *= un
grouped_columns = copy(allcolumns)
else
Expand All @@ -34,7 +34,7 @@ function meltdata(U::AbstractDataFrame, colgroups_::Vector{Col.GroupedColumn})

# allocate vectors for grouped columns
for (j, colgroup) in enumerate(colgroups)
cols = colgroup.columns===nothing ? allcolumns : colgroup.columns
cols = colgroup.columns === nothing ? allcolumns : colgroup.columns

# figure the grouped common column type
firstcol = U[first(cols)]
Expand Down Expand Up @@ -64,7 +64,7 @@ function meltdata(U::AbstractDataFrame, colgroups_::Vector{Col.GroupedColumn})
col_indicators = Array{Symbol}(undef, vm, length(colgroups))
row_indicators = Array{Int}(undef, vm, length(colgroups))

colidxs = [colgroup.columns===nothing ? collect(allcolumns) : colgroup.columns
colidxs = [colgroup.columns === nothing ? collect(allcolumns) : colgroup.columns
for colgroup in colgroups]

vi = 1
Expand Down
4 changes: 2 additions & 2 deletions src/geom/boxplot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ function render(geom::BoxplotGeometry, theme::Gadfly.Theme, aes::Gadfly.Aestheti
svgclass("geometry"))

# Outliers
if !geom.suppress_outliers && aes.outliers != nothing && !isempty(aes.outliers)
if !geom.suppress_outliers && aes.outliers !== nothing && !isempty(aes.outliers)
xys = collect(Iterators.flatten(zip(cycle([x]), ys, cycle([c]))
for (x, ys, c) in zip(xs, aes.outliers, cs)))
compose!(ctx, (context(),
Expand All @@ -133,7 +133,7 @@ function render(geom::BoxplotGeometry, theme::Gadfly.Theme, aes::Gadfly.Aestheti
end

# Middle
if aes.middle != nothing
if aes.middle !== nothing
compose!(ctx, (
context(order=1),
Compose.line([[(x - fw/2, mid), (x + fw/2, mid)]
Expand Down
4 changes: 2 additions & 2 deletions src/geom/errorbar.jl
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ function render(geom::YErrorBarGeometry, theme::Gadfly.Theme, aes::Gadfly.Aesthe
stroke([theme.stroke_color(c) for c in aes.color]),
linewidth(theme.line_width))

(aes.color_key_continuous == true || aes.color == nothing) || compose!(ctx,
(aes.color_key_continuous == true || aes.color === nothing) || compose!(ctx,
svgclass([svg_color_class_from_label(aes.color_label([c])[1]) for c in aes.color]))

return ctx
Expand Down Expand Up @@ -148,7 +148,7 @@ function render(geom::XErrorBarGeometry, theme::Gadfly.Theme, aes::Gadfly.Aesthe
stroke([theme.stroke_color(c) for c in aes.color]),
linewidth(theme.line_width))

(aes.color_key_continuous == true || aes.color == nothing) || compose!(ctx,
(aes.color_key_continuous == true || aes.color === nothing) || compose!(ctx,
svgclass([svg_color_class_from_label(aes.color_label([c])[1])
for c in aes.color]))

Expand Down
6 changes: 3 additions & 3 deletions src/geom/hvabline.jl
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,12 @@ const abline = ABLineGeometry
element_aesthetics(geom::ABLineGeometry) = [:intercept, :slope]

function render(geom::ABLineGeometry, theme::Gadfly.Theme, aes::Gadfly.Aesthetics)
if aes.intercept == nothing && aes.slope == nothing
if aes.intercept === nothing && aes.slope === nothing
aes.intercept = [0]
aes.slope = [1]
elseif aes.intercept == nothing
elseif aes.intercept === nothing
aes.intercept = fill(0,length(aes.slope))
elseif aes.slope == nothing
elseif aes.slope === nothing
aes.slope = fill(1,length(aes.intercept))
end
Gadfly.assert_aesthetics_equal_length("Geom.line", aes, element_aesthetics(geom)...)
Expand Down
4 changes: 2 additions & 2 deletions src/geom/label.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function deferred_label_context(geom::LabelGeometry,

num_labels = length(aes.label)

if aes.size == nothing
if aes.size === nothing
padding = fill(theme.point_size, num_labels) .+ theme.label_padding
else
padding = aes.size .+ theme.label_padding
Expand Down Expand Up @@ -279,7 +279,7 @@ function render(geom::LabelGeometry, theme::Gadfly.Theme, aes::Gadfly.Aesthetics
end

hpos, vpos, xoff, yoff = label_layouts[geom.position]
if aes.size == nothing
if aes.size === nothing
offsets = [(xoff*(theme.point_size + theme.label_padding),
yoff*(theme.point_size + theme.label_padding))]
else
Expand Down
Loading