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

Make plot layers & inner subplot layers consistent #1520

Open
wants to merge 1 commit 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
31 changes: 17 additions & 14 deletions src/Gadfly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,12 @@ function layer(data_source,
for element in elements
add_plot_element!(lyrs, element)
end
lyrs
for l in lyrs
if isempty(l.statistics) && !isa(l.geom, Geom.Nil) && !isa(l.geom, Geom.SubplotGeometry)
l.statistics = [default_statistic(l.geom)]
end
end
return lyrs
end

"""
Expand Down Expand Up @@ -235,11 +240,12 @@ layers(p::Plot) = p.layers

function add_plot_element!(p::Plot, arg::GeometryElement)
if !isempty(p.layers) && isa(p.layers[end].geom, Geom.Nil)
p.layers[end].geom = arg
newlayer = p.layers[end]
newlayer.geom = arg
isempty(newlayer.statistics) && (newlayer.statistics = [default_statistic(arg)])
else
layer = Layer()
layer.geom = arg
push!(p.layers, layer)
lyr = first(layer(arg))
push!(p.layers, lyr)
end
end

Expand Down Expand Up @@ -377,9 +383,8 @@ end
#
function render_prepare(plot::Plot)
if isempty(plot.layers)
layer = Layer()
layer.geom = isempty(plot.mapping) ? Geom.blank() : Geom.point()
push!(plot.layers, layer)
lyr = first(layer((isempty(plot.mapping) ? Geom.blank() : Geom.point())))
push!(plot.layers, lyr)
end

# TODO: When subplots are given in multiple layers, we should rearrange,
Expand All @@ -406,7 +411,7 @@ function render_prepare(plot::Plot)

layer.data_source===nothing && (layer.data_source = plot.data_source)

geom_aesthetics = intersect(element_aesthetics(layer.geom), plot_aesthetics)
geom_aesthetics = intersect(vcat(element_aesthetics(layer.geom), input_aesthetics.(layer.statistics)...), plot_aesthetics)
geom_dict = filter(x->in(x.first, geom_aesthetics), plot.mapping)
layer.mapping = merge(geom_dict, layer.mapping)

Expand All @@ -427,8 +432,7 @@ function render_prepare(plot::Plot)

subplot_layer.data_source===nothing && (subplot_layer.data_source = layer.data_source)

geom_aes = vcat(element_aesthetics(subplot_layer.geom), [:xgroup,:ygroup], input_aesthetics(default_statistic(subplot_layer.geom)))
!isempty(subplot_layer.statistics) && append!(geom_aes, input_aesthetics(subplot_layer.statistics[1]))
geom_aes = vcat(element_aesthetics(subplot_layer.geom), [:xgroup,:ygroup], input_aesthetics.(subplot_layer.statistics)...)
geom_aesthetics = intersect(geom_aes, plot_aesthetics)
geom_dict = filter(x->in(x.first, geom_aesthetics), plot.mapping)
subplot_layer.mapping = merge(geom_dict, subplot_layer.mapping)
Expand All @@ -454,10 +458,9 @@ function render_prepare(plot::Plot)
layer_stats = Array{Vector{StatisticElement}}(undef, length(plot.layers))
for (i, layer) in enumerate(plot.layers)
if isa(layer.geom, Geom.SubplotGeometry)
layer_stats[i] = [isempty(subplot_layer.statistics) ? default_statistic(subplot_layer.geom) : subplot_layer.statistics[1]
for subplot_layer in layers(layer.geom)]
layer_stats[i] = [subplot_layer.statistics[1] for subplot_layer in layers(layer.geom)]
else
layer_stats[i] = isempty(layer.statistics) ? [default_statistic(layer.geom)] : layer.statistics
layer_stats[i] = layer.statistics
end
end

Expand Down
2 changes: 1 addition & 1 deletion src/geom/hvabline.jl
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ function render(geom::ABLineGeometry, theme::Gadfly.Theme, aes::Gadfly.Aesthetic
if typeof(aes.y) <: Array{Function}
lowx, highx = aes.xmin[1], aes.xmax[1]
else
lowx, highx = extrema(aes.x)
lowx, highx = extrema(aes.x[isfinite.(aes.x)])
end

# extending the line to width 3 times x-range of data should be enough
Expand Down
22 changes: 11 additions & 11 deletions src/geom/subplot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,19 @@ end

function add_subplot_element(p::SubplotGeometry, arg::Gadfly.GeometryElement)
if !isempty(p.layers) && isa(p.layers[end].geom, Geom.Nil)
p.layers[end].geom = arg
newlayer = p.layers[end]
newlayer.geom = arg
isempty(newlayer.statistics) && (newlayer.statistics = [default_statistic(arg)])
else
layer = Layer()
layer.geom = arg
push!(p.layers, layer)
lyr = first(layer(arg))
push!(p.layers, lyr)
end
end

add_subplot_element(subplot::SubplotGeometry, arg::Gadfly.StatisticElement) =
push!(subplot.statistics, arg)
function add_subplot_element(subplot::SubplotGeometry, arg::Gadfly.StatisticElement)
isempty(subplot.layers) && push!(subplot.layers, Layer())
push!(subplot.layers[end].statistics, arg)
end

function add_subplot_element(subplot::SubplotGeometry, arg::Gadfly.ScaleElement)
push!(subplot.scales, arg)
Expand Down Expand Up @@ -119,8 +122,7 @@ end

element_coordinate_type(::SubplotGrid) = Gadfly.Coord.subplot_grid

default_statistic(geom::SubplotGrid) = isempty(geom.statistics) ?
[default_statistic(l.geom) for l in geom.layers] : geom.statistics
default_statistic(geom::SubplotGrid) = [first(l.statistics) for l in geom.layers]


# Render a subplot grid geometry, which consists of rendering and arranging
Expand Down Expand Up @@ -156,9 +158,7 @@ function render(geom::SubplotGrid, theme::Gadfly.Theme,

coord = geom.coord
plot_stats = Gadfly.StatisticElement[stat for stat in geom.statistics]
layer_stats = [isempty(layer.statistics) ?
Gadfly.StatisticElement[Geom.default_statistic(layer.geom)] : layer.statistics
for layer in geom.layers]
layer_stats = Vector{Gadfly.StatisticElement}[layer.statistics for layer in geom.layers]

for i in 1:n, j in 1:m
Scale.apply_scales(geom.scales,
Expand Down
31 changes: 16 additions & 15 deletions src/statistics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1695,29 +1695,30 @@ function apply_statistic(stat::ViolinStatistic,

isa(aes.y[1], Real) || error("Kernel density estimation only works on Real types.")

grouped_y = Dict(1=>aes.y)
grouped_color = Dict{Int, Gadfly.ColorOrNothing}(1=>nothing)
ux = unique(aes.x)
uxflag = length(ux) < length(aes.x)
colorflag = aes.color != nothing

uxflag && (grouped_y = Dict(x=>aes.y[aes.x.==x] for x in ux))
colorflag = aes.color !== nothing
aes_x = aes.x==nothing ? [1] : aes.x
aes_color = colorflag ? aes.color : [nothing]
XT, CT, YT = eltype(aes_x), eltype(aes_color), eltype(aes.y)
groups = collect((Tuple{XT, CT}), Compose.cyclezip(aes_x, aes_color))
ugroups = unique(groups)
nugroups = length(ugroups)

grouped_color = (colorflag ? Dict(x=>first(aes.color[aes.x.==x]) for x in ux) :
uxflag && Dict(x=>nothing for x in ux) )
grouped_y = if nugroups==1
Dict(ugroups[1]=>aes.y)
else
Dict(g=>aes.y[groups.==[g]] for g in ugroups)
end

aes.x = Array{Float64}(undef, 0)
aes.y = Array{Float64}(undef, 0)
aes.width = Array{Float64}(undef, 0)
colors = eltype(aes.color)[]
aes.x, aes.y, aes.width = XT[], Float64[], Float64[]
colors = CT[]

for (x, ys) in grouped_y
for ((x, c), ys) in grouped_y
window = stat.n > 1 ? KernelDensity.default_bandwidth(ys) : 0.1
f = KernelDensity.kde(ys, bandwidth=window, npoints=stat.n)
append!(aes.x, fill(x, length(f.x)))
append!(aes.y, f.x)
append!(aes.width, f.density)
append!(colors, fill(grouped_color[x], length(f.x)))
append!(colors, fill(c, length(f.x)))
end

colorflag && (aes.color = colors)
Expand Down