From 9c49f18713b63bb3b91b4f01c8c82cdfd5d31d27 Mon Sep 17 00:00:00 2001 From: Mattriks Date: Mon, 6 Apr 2020 21:27:00 +1000 Subject: [PATCH 1/2] updates to ShapeKey --- src/guide/keys.jl | 25 ++++++++++++++----------- src/misc.jl | 2 +- src/scale.jl | 20 +++++++++++++++++--- test/testscripts/Guide_shapekey.jl | 17 +++++++++++++---- 4 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/guide/keys.jl b/src/guide/keys.jl index 43f7132b9..335ed0337 100644 --- a/src/guide/keys.jl +++ b/src/guide/keys.jl @@ -7,33 +7,36 @@ struct ShapeKey <: Gadfly.GuideElement title::AbstractString labels::Vector{String} pos::Vector + visible::Bool end -ShapeKey(;title="Shape", labels=[""], pos=Float64[]) = ShapeKey(title, labels, pos) +ShapeKey(;title="Shape", labels=String[], pos=[], visible=true) = ShapeKey(title, labels, pos, visible) +ShapeKey(v::Nothing) = ShapeKey(visible=false) +ShapeKey(title::AbstractString, labels::Vector{String}, pos::Vector) = ShapeKey(title, labels, pos, true) """ - Guide.shapekey[(; title="Shape", labels=[""], pos=Float64[])] + Guide.shapekey[(; title="Shape", labels=String[], pos=Float64[])] Guide.shapekey(title, labels, pos) Enable control of the auto-generated shapekey. Set the key `title` and the item `labels`. `pos` overrides [Theme(key_position=)](@ref Gadfly) and can be in either relative (e.g. [0.7w, 0.2h] is the lower right quadrant), absolute (e.g. [0mm, -0mm]), or plot scale (e.g. [0,0]) coordinates. +0mm]), or plot scale (e.g. [0,0]) coordinates. `Guide.shapekey(nothing)` will hide the key. """ const shapekey = ShapeKey -function Guide.render(guide::Guide.ShapeKey, theme::Gadfly.Theme, aes::Gadfly.Aesthetics) +function render(guide::ShapeKey, theme::Gadfly.Theme, aes::Gadfly.Aesthetics) - (theme.key_position == :none) && return Gadfly.Guide.PositionedGuide[] + (theme.key_position == :none || !guide.visible || isa(aes.shape[1], Function)) && return PositionedGuide[] gpos = guide.pos - (theme.key_position == :inside) && (gpos == Float64[]) && (gpos = [0.7w, 0.25h]) + (theme.key_position == :inside) && isempty(gpos) && (gpos = [0.7w, 0.25h]) - # Aesthetics for keys: shape_key_title, shape_label (Function), shape_key_shapes (AbstractDict) + # Aesthetics for keys: shape_key_title, shape_label (Function), shape_key_shapes (AbstractDict) nshapes = length(unique(aes.shape)) - guide_title = (guide.title!="Shape" || aes.shape_key_title==nothing) ? guide.title : aes.shape_key_title - shape_key_labels = !(guide.labels==[""]) ? guide.labels : aes.shape_label(1:nshapes) + guide_title = (guide.titleā‰ "Shape" || aes.shape_key_title==nothing) ? guide.title : aes.shape_key_title + shape_key_labels = isempty(guide.labels) ? aes.shape_label(1:nshapes) : guide.labels colors = [nothing] if (aes.shape_key_title !=nothing) && (aes.color_key_title==aes.shape_key_title) @@ -44,7 +47,7 @@ function Guide.render(guide::Guide.ShapeKey, theme::Gadfly.Theme, aes::Gadfly.Ae ctxs = render_discrete_key(shape_key_labels, title_context, title_width, theme, shapes=1:nshapes, colors=colors) position = right_guide_position - if gpos != Float64[] + if !isempty(gpos) position = over_guide_position ctxs = [compose(context(), (context(gpos[1],gpos[2]), ctxs[1]))] elseif theme.key_position == :left @@ -55,7 +58,7 @@ function Guide.render(guide::Guide.ShapeKey, theme::Gadfly.Theme, aes::Gadfly.Ae position = bottom_guide_position end - return [Guide.PositionedGuide(ctxs, 0, position)] + return [PositionedGuide(ctxs, 0, position)] end diff --git a/src/misc.jl b/src/misc.jl index 4a3591600..e20f160fc 100644 --- a/src/misc.jl +++ b/src/misc.jl @@ -338,6 +338,6 @@ function discretize_make_ia(values::CategoricalArray{T}, levels::Vector) where { return IndirectArray(index, convert(Vector{T},levels)) end function discretize_make_ia(values::CategoricalArray{T}, levels::CategoricalVector{T}) where T - _levels = map!(t -> ismissing(t) ? t : get(t), Vector{T}(length(levels)), levels) + _levels = map!(t -> ismissing(t) ? t : get(t), Vector{T}(undef, length(levels)), levels) discretize_make_ia(values, _levels) end diff --git a/src/scale.jl b/src/scale.jl index a8104d431..dddfdc7c2 100644 --- a/src/scale.jl +++ b/src/scale.jl @@ -366,13 +366,27 @@ alpha_discrete(; labels=nothing, levels=nothing, order=nothing) = function apply_scale(scale::DiscreteScale, aess::Vector{Gadfly.Aesthetics}, datas::Gadfly.Data...) + + + d = [] + for data in datas + for var in scale.vars + datavar = getfield(data, var) + datavar!=nothing && append!(d, skipmissing(datavar)) + end + end + levelset = unique(d) + + scale_levels = (scale.levels==nothing) ? [levelset...] : scale.levels + for (aes, data) in zip(aess, datas) for var in scale.vars label_var = Symbol(var, "_label") - getfield(data, var) === nothing && continue + datavar = getfield(data, var) + datavar===nothing && continue - disc_data = discretize(getfield(data, var), scale.levels, scale.order) - setfield!(aes, var, discretize_make_ia(Int64.(disc_data.index))) + disc_data = discretize(datavar, scale_levels, scale.order) + setfield!(aes, var, discretize_make_ia(disc_data.index)) # The leveler for discrete scales is a closure over the discretized data. if scale.labels === nothing diff --git a/test/testscripts/Guide_shapekey.jl b/test/testscripts/Guide_shapekey.jl index 21713f8fb..51c83c4af 100644 --- a/test/testscripts/Guide_shapekey.jl +++ b/test/testscripts/Guide_shapekey.jl @@ -1,8 +1,8 @@ using Compose, DataFrames, Gadfly -set_default_plot_size(9inch, 3.3inch) +set_default_plot_size(9inch, 6inch) -theme1 = Theme(point_size=3mm) +theme1 = Theme(point_size=6pt) coord1 = Coord.cartesian(xmin=0.0, xmax=6.0) D = DataFrame(x=1:5, y=[0.768448, 0.940515, 0.673959, 0.395453, 0.313244], @@ -20,7 +20,16 @@ pb = plot(D, x=:x, y=:y, shape=:V1, color=:V1, pc = plot(D, x=:x, y=:y, shape=:V1, color=:V2, coord1, Guide.colorkey(title="Color"), Guide.shapekey(title="Shape ", pos=[0.74w,-0.27h]), - Theme(point_size=3mm, key_swatch_color="slategrey"), + Theme(point_size=6pt, key_swatch_color="slategrey"), Guide.title("Shape!=Color") ) -hstack(pa,pb,pc) + +pd = plot(D, x=:x, y=:y, shape=[Shape.square], size=[8pt]) +pe = plot() +pf = plot(Theme(point_size=6pt, alphas=[0.6]), + layer(x=0.5:4, y=D.y[1:4], shape=["Gr1"]), + layer(x=1:4, y=D.y[1:4], shape=["Gr2"]) ) + + + +gridstack([pa pb pc; pd pe pf]) From a96839e6422c1af971e65399a8b9bbced4720451 Mon Sep 17 00:00:00 2001 From: Mattriks Date: Mon, 13 Apr 2020 20:40:25 +1000 Subject: [PATCH 2/2] Example for Gallery Shapes page --- docs/src/gallery/shapes.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/docs/src/gallery/shapes.md b/docs/src/gallery/shapes.md index 220ceebdb..92634c052 100644 --- a/docs/src/gallery/shapes.md +++ b/docs/src/gallery/shapes.md @@ -1,11 +1,20 @@ # Shapes -## [`Shape.square`](@ref) +## [`Shape.square`](@ref) and friends ```@example using Gadfly, RDatasets -set_default_plot_size(14cm, 8cm) -plot(dataset("HistData","DrinksWages"), - x="Wage", y="Drinks", shape=[Shape.square], - Geom.point, Scale.y_log10) +set_default_plot_size(21cm, 8cm) + +p1 = plot(dataset("HistData","DrinksWages"), x="Wage", y="Drinks", + shape=[Shape.square], Scale.y_log10) + +aww, mws = dataset("MASS", "Animals"), dataset("quantreg", "Mammals") +p2 = plot( layer(aww, x=:Body, y=:Brain, shape=["Brain weight"]), + layer(mws, x=:Weight, y=:Speed, shape=["Run speed"]), + Scale.x_log10, Scale.y_log10, Guide.xlabel("Body weight"), + Guide.ylabel("Brain weight and Run speed"), + Theme(point_shapes=[Shape.circle, Shape.star1], alphas=[0.0], + discrete_highlight_color=identity) ) +hstack(p1, p2) ```