Skip to content

Commit

Permalink
Merge pull request #1411 from Mattriks/guide_shapekey
Browse files Browse the repository at this point in the history
Guide.shapekey updates
  • Loading branch information
Mattriks authored Apr 15, 2020
2 parents 1ffc0fc + a96839e commit eb49440
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 24 deletions.
19 changes: 14 additions & 5 deletions docs/src/gallery/shapes.md
Original file line number Diff line number Diff line change
@@ -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)
```
25 changes: 14 additions & 11 deletions src/guide/keys.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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


Expand Down
2 changes: 1 addition & 1 deletion src/misc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
20 changes: 17 additions & 3 deletions src/scale.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 13 additions & 4 deletions test/testscripts/Guide_shapekey.jl
Original file line number Diff line number Diff line change
@@ -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],
Expand All @@ -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])

0 comments on commit eb49440

Please sign in to comment.